2011年2月28日 星期一

git branch

後記:寫一寫覺得這個系列對初學者可能不太容易了解… XD 要寫出簡單易懂的說明還真是需要花點功夫,想想拖稿太久還是作罷。
用 Git 就是要愛用 Branch 啊,Branch 很好用,開 Branch 不用錢。開 Branch 的情境除了在上一篇中提到因應產品 release 需求的 stable/production branch 之外,其他開 branch 情況有:
  • 帶有實驗性質的變更,例如想改寫新的演算法、重構程式碼等
  • 新功能 feature 開發
  • Bug fixes,你可能需要做些實驗才知道到底怎麼修
這些事情都可以先在本地開 local branch 做,而不需要立即 Push 分享給別人。

git branch <new_branch_name> 建立本地 local branch
git branch -m <old_name> <new_name> 改名字 (如果有同名會失敗,改用 -M 可以強制覆蓋)
git branch 列出目前有那些 branch 以及目前在那個 branch
git checkout <branch_name> 切換 branch (注意到如果你有檔案修改了卻還沒 commit,會不能切換 branch,解法稍後會談)
git checkout -b <new_branch_name> (<from_branch_name>) 本地建立 branch 並立即 checkout 切換過去
git branch -d <branch_name> 刪除 local branch
開 Branch 最大的好處除了可以不影響 stable 和其他分支版本的開發,另一個超棒的地方是”你可以決定 Merge 的方式”。Git 的 Merge 方式可以分成四種:
  • Straight merge 預設的合併模式,會有全部的被合併的 branch commits 記錄加上一個 merge-commit,看線圖會有兩條 Parents 線,並保留所有 commit log。
  • Squashed commit 壓縮成只有一個 merge-commit,不會有被合併的 log。SVN 的 merge 即是如此。
  • cherry-pick 只合併指定的 commit
  • rebase 變更 branch 的分支點:找到要合併的兩個 branch 的共同的祖先,然後先只用要被 merge 的 branch 來 commit 一遍,然後再用目前 branch 再 commit 上去。這方式僅適合還沒分享給別人的 local branch,因為等於砍掉重練 commit log。
其中 rebase 比較難理解會在下一篇再詳述:

git merge <branch_name> 合併另一個 branch,若沒有 conflict 衝突會直接 commit。若需要解決衝突則會再多一個 commit。
git merge --squash <branch_name> 將另一個 branch 的 commit 合併為一筆,特別適合需要做實驗的 fixes bug 或 new feature,最後只留結果。合併完不會幫你先 commit。
git cherry-pick 321d76f 只合併特定其中一個 commit。如果要合併多個,可以加上 -n 指令就不會先幫你 commit,這樣可以多 pick幾個要合併的 commit,最後再 git commit 即可。
使用 merge 可能會有部分程式碼會 conflict 衝突:簡單的情況只要編輯檔案處理 <<<< ===== >>>>> 即可,然後重新 add 到 staging area 並 commit (沒有像 SVN 的 resolve 指令)。複雜一點的可以再用 git mergetool 選檔案合併的 GUI 工具 (OS X 下面可以用 opendiff, linux 可以用 kdiff3 ),處理好後 git commit。
一旦 merge 好了,git branch -d <branch_name> 可以刪除 branch。但如果要刪除的 branch 還沒有合併,就會有錯誤訊息。如果真的要強制刪除可以用 -D
Git 的 working tree 是從 SVN 換過來一個不習慣的地方,因為它只是一個工作暫存區,在切換 Branch 時就會整個換掉。也因為如此,如果有檔案有修改還沒有 commit 出去,切換 branch 時就會出現 error 不能切換 (除非是新的 untracking 檔案),例如有修改還沒 add 會出現 error: Entry ‘ooxx’ not uptodate. Cannot merge. 有修改且已經add(還沒ci)會出現 error: Entry ‘ooxx’ would be overwritten by merge. Cannot merge.
最理想的處理當然是事情剛好做到一個段落,把東西 commit 出去才切換 branch 做事。不過事情總有臨時,如果要換 branch 的暫時的解決方式是使用 git stash 會先把修改暫存下來,要回復則執行 git stash pop。下一篇等你學會 git reset 之後,你會發現就算把還沒完成的東西 commit 也不會怎麼樣,只要還沒 push 出去一切 commit 紀錄都是可以改的。

Remote repo. 操作

首先要認識的是 Protocol,像在 Github 上面看自己的 Project,會有分 Public Clone URL 跟 Your Clone URL,這有什麼差?
  • git://github.com/ihower/project.git 這種的是使用 Git 自己的 prototol,優點是速度快,但是沒有認證機制,只適合 read only (port:9418)
  • git@github.com/ihower/project.git 這種的是使用 SSH,可以有認證(SSH key)
  • Git 也可以透過 HTTPS 的方式,不過速度較慢,比較適合對 firewall 有限制的情況
其中 Github 就是同時用 SSH + Git protocol,兼顧認證需求及速度。

git clone <remote_address>
git checkout --track -b foobar origin/foobar 將遠端的 branch checkout 回來並建立一個新的 local branch,加上 --track 表示你之後還要pull、push回去,所以請 Git 記住對應關係。
git pull (<local_branch_name> origin/<remote_branch_name>) 去遠端 fetch 新版並 merge 進 local branch
git push 將 local branch 的 commit 紀錄更新到遠端
git pull 要注意的是,如果別人在你上次 pull 之後有 push 新東西上去(也就是說跟你的 branch 產生分岔了),此時有兩種情況: 一是 Git 可以順利 auto merge 的話,git 會自動多一次 merge commit,這也就為什麼常常 log 會跑出 Merge branch ‘master’ of git@foobar.com。二是如果有 conflict,這時候就需要你手動處理然後 commit。話說如果覺得這種 local branch 和 remote branch 的 merge commit log 很煩,建議可以改使用 git pull –rebase 指令來變成 fast-forward 形式 (就會變得像 svn up,而不會有 merge commit log)。rebase 的意思可能要下一篇才會詳細說明的清楚,簡單的說(?),就是先砍掉 local branch 分岔點之後自己的 commit,然後把遠端的 commit 先一個個 apply 進來,最後再把自己的 commit 再 apply 進去 (如果有 conflict 會中途停下來,等你修好才會繼續 apply),如此一來看線圖就會變成一條線而已,也就沒有所謂 merge 這個動作了。
git push 預設的遠端是 origin,並且會將所有有和 remote 有對應的 local branch 都 push 上去。如果要把新的 local branch push 上去,需要下 git push origin <local_vranch_name> 指令。
git push 也可能會失敗,例如出現 ! [rejected] master -> master (non-fast forward),這個 non-fast forward 的意思是你的 parent commit 和遠端的不相同,也就是線圖有分岔,需要先 pull 回來處理好 merge 才能 push 上去。
fast-forward 在 Git 是一種 merge 術語,當 B branch (例如一個 local branch) 是從 A branch (例如一個 remote branch) 的最新版(HEAD)分支出來的,那當 A 要把 B merge 進來時,因為 B 的 parent commit 是 A 的 HEAD,所以這兩個 branch 唯一的差異就是 B 後來的 commit 而已,而不會有任何 conflict。所以實際上的動作只要把 A 的 HEAD 改成 B 的 HEAD 就好了,線圖上這兩個 branch 根本是同一條線,此謂 fast-forward。
其他操作還有:

git fetch 把遠端的 branch 更新下載回來,但不會 merge 到 local branch
git branch -r 顯示 local 有追蹤的遠端 branch。注意到你不能直接修改這個 remote branch,一定要用一個 local branch 對應它。
git remote show origin 顯示遠端 server 的 branch
git remote add foobar git:// 可以新增別的 repo. 位置,於是 pull 的時候就可以指定要從哪一個遠端更新回來。
git push origin :foobar 刪除遠端的 branch
因為遠端的操作指令比較雜,所以也有人寫了 git_remote_branch 來簡化操作。

Using git for collaboration

go to the link

http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html

To see
using git for collaboration


Pull command

The "pull" command thus performs two operations: it fetches changes from a remote branch, then merges them into the current branch.

2011年2月24日 星期四

iOS-programming_question

1). Iphone 開發方式?
XCode , 搭配 Git
2). Iphone 如何與網路溝通? 實例?
httprequest ?
http://developer.apple.com/library/ios/#documentation/Networking/Conceptual/CFNetwork/CFHTTPTasks/CFHTTPTasks.html
CFNetwork Concepts
http://developer.apple.com/library/ios/#documentation/Networking/Conceptual/CFNetwork/Concepts/Concepts.html#//apple_ref/doc/uid/TP30001132-CH4-DontLinkElementID_13

3). Iphone 如何取得網站上的資料, 並進行解析?
    . XML 如何進行交換, 實例?
http://developer.apple.com/library/ios/#samplecode/SeismicXML/Introduction/Intro.html  
  
    . 如何將網站上的資料和圖片下載至手機裡, 以供使用?
Working with Streams
http://developer.apple.com/library/ios/#documentation/Networking/Conceptual/CFNetwork/CFStreamTasks/CFStreamTasks.html#//apple_ref/doc/uid/TP30000230-61466

    . 如何將手機上的圖片上傳至網站裡?

4). SQLite 如何應用實做? 如何將交換(XML)所得資料寫入 SQLite?
http://iphoneipad-develop.blogspot.com/2011/02/using-sqlite.html

5). Iphone, Ipad 的開發方式有何不同? 我該如何著手開發 Ipad?
6). 帶領我和榆翔實作一個小的 Project, 例如:產品資訊(含圖片)下載 Demo App.
7). 量 GG App 的實做是否可能?
8). 如何撰寫 Iphone 開發文件?
9). Object-C 如何使用 base64 編碼?
10). 委派的實作與原理

A: 請delegate幫我摘水果
A: 要當我的delegate必須遵守我的protocol 也就是會爬樹

B: 我來當A的delegate
Compiler: B你有遵守protocol嗎
B: 有 我會爬樹

B to A: 我摘到水果了 請吃

C: 我也要當A的delegate
Compiler: C你有遵守protocol嗎
C: 沒有 我不會爬樹
Compiler: 那C你會害我們crash
Basically, delegation is a way of allowing objects to interact with each other without creating strong interdependencies between them, since this makes the design of your application less flexible. Instead of objects controlling one another, they can have a delegate which they send (or delegate) messages to, and the delegate does whatever they do, in order to respond and act to this message, and then usually return something back to the other object.
Delegation is also a better alternative to subclassing. Instead of you having to create your own custom classes to slightly alter the way that other objects behave, or pass them data, delegation allows objects to send messages to their delegates to do work for them without the overhead of creating subclasses to make minor changes to other objects.
Of course, the main disadvantage of delegation is that the delegate methods available are dependent on what the Apple engineers foresee as being useful and what common implementations they expect people to need, which imposes a restriction on what you can achieve. Although, as Quinn Taylor pointed out, this is specific to the Cocoa frameworks and so doesn't apply in all situations.
If delegation is an option over subclassing, then take it, because it's a much cleaner way to manage your code and interactions between objects.

11). Object-C 如何判斷變數型態? ( C++ 是 typeof ) ->  (instanceof) ?
Try [myObject class] for returning the class of an object.
[myObject isKindOfClass:[NSString class]]
[myObject isKindOfClass:[UIImageView class]]

12). 如何設計一支 APP, 能在網頁上直接點圖下載? 或是點了圖後, 會出現是否下載的對話框?
13). Xcode 裡選擇開發型態的差別:什麼時候該用 application based on windows? ... 什麼是時候該 ...

14). 如何在 Object-C 裡使用 base64 或其他編碼, 進行編解碼 ?

15). Open GL 如何使用? or 2D 繪圖?
http://www.discuss.com.hk/archiver/?tid-12945915.html

Using SQLite

iPhone 上的應用程式可以使用 Plist 或 XML 檔案去記錄資料,如果資料類型比較簡單,資料和資料之間沒有關聯性,資料數量不多,使用 Plist 或 XML 檔案已經足夠應付。如果需要記錄大量並擁複雜關聯性的資料時,還是建議使用資料庫去去儲存資料好。

iPhone 的應用程式可以使用 SQLite 去作為資料庫系統,SQLite 是超輕量版的一款資料庫系統,完全不像常用的資料庫系統,例如: MySQL,PostgreSQL,Oracle 等等。SQLite 不用安裝,整個資料庫就是以一個檔案的型式存在,存取資料靠 iPhone SDK 提供的 Library 就可以了。由於iPhone SDK 已經內置了 SQLite 的 Library 檔案,所以不用擔心兼容性的問題,就算是遲些出到 iPhone 5, 6, 7 也沒問題的。操作方面和常用的資料庫系統差不多,一樣可以使用 SQL 去操作。

在寫程式之前要先製作好資料庫才可以,我建議使用 FireFox 的插件 - SQLite Manager
下載網址: https://addons.mozilla.org/en-US/firefox/addon/5817/

SQLite Manager 在 Mac OSX, Linux 或 Windows 環境也一樣可以用到,只要裝到 FireFox 就可以用到。

怎麼使用 SQLite Manager 就不多講了,以下是我的資訊庫的 DDL 加上 DML:

DROP TABLE IF EXISTS "customer";
CREATE TABLE "customer" ("pid" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "first_name" VARCHAR, "last_name" VARCHAR);
INSERT INTO "customer" VALUES(1,'Lawrence','Cheung');
INSERT INTO "customer" VALUES(2,'Tom','Chan');
INSERT INTO "customer" VALUES(3,'Ken','Choi');
DROP TABLE IF EXISTS "sqlite_sequence";
CREATE TABLE sqlite_sequence(name,seq);
INSERT INTO "sqlite_sequence" VALUES('customer',3);

你要先在 Project 內增加 SQLIte 的 Library 才使用到 SQLIte 資料庫,將 libsqlite3.0.dylib 加入到 Framework 內。

為了不經常打開資料庫的連接,我使用一個 Singleton 類別去保持資料庫的連接。這個類別的程式碼:
DBHelper.h:
#import <sqlite3.h>

@interface DBHelper : NSObject {
 sqlite3 *database;
}

@property(readonly, nonatomic) sqlite3 *database;

+ (DBHelper *) newInstance;
- (void) openDatabase;
- (void) closeDatabase;
- (NSString *) getDatabaseFullPath;
- (void) copyDatabaseIfNeeded;
- (sqlite3_stmt *) executeQuery:(NSString *) query;

@end

DBHelper.m:
#import "DBHelper.h"

@implementation DBHelper

static DBHelper *instance = nil;

NSString *DB_NAME = @"sample";
NSString *DB_EXT = @".sqlite";

@synthesize database;

+ (DBHelper *) newInstance{
   @synchronized(self) {
      if (instance == nil){
         instance = [[DBHelper alloc]init];
         [instance openDatabase];
      }
   }
   return instance;
}

+ (id)allocWithZone:(NSZone *)zone {
   @synchronized(self) {
      if (instance == nil) {
         instance = [super allocWithZone:zone];
         return instance;        
      }
   }
   return nil;
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;
}

- (void)release {
    //do nothing
}

- (id)autorelease {
    return self;
}

- (void) openDatabase{
    if (!database){
      [self copyDatabaseIfNeeded];
      int result = sqlite3_open([[self getDatabaseFullPath] UTF8String], &database);
      if (result != SQLITE_OK){
         NSAssert(0, @"Failed to open database");
      }
   }
}

- (void) closeDatabase{
    if (database){
        sqlite3_close(database);
    }
}

- (void) copyDatabaseIfNeeded{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSString *dbPath = [self getDatabaseFullPath];
    BOOL success = [fileManager fileExistsAtPath:dbPath]; 
 
    if(!success) {
  
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@", DB_NAME, DB_EXT]];
        success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
        NSLog(@"Database file copied from bundle to %@", dbPath);
  
        if (!success){ 
            NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        }
        
    } else {
        
        NSLog(@"Database file found at path %@", dbPath);
  
    }
}

- (NSString *) getDatabaseFullPath{
   NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
   NSString *documentsDirectory = [paths objectAtIndex:0];
   NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@", DB_NAME, DB_EXT]];
   return path;
}

- (sqlite3_stmt *) executeQuery:(NSString *) query{
   sqlite3_stmt *statement;
   sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil);
   return statement;
}

@end

我在這個類別初始化同時會打開資料庫的連接,要在 iPhone 開啟 SQLite 資料庫前,必須要將資料庫複製到 Documents 目錄內,而其他類別要用 SQL 向資料庫查詢資料只要執行executeQuery 就可以了。

向資料庫查詢資料:
DBHelper *dbHelper = [DBHelper newInstance];
    
NSString *sql = @"SELECT customer.pid, customer.first_name, customer.last_name FROM customer";
sqlite3_stmt *statement = [dbHelper executeQuery:sql];
    
while(sqlite3_step(statement) == SQLITE_ROW){
    int pid = sqlite3_column_int(statement, 0);
    NSString *firstName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
    NSString *lastName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)];
    NSLog(@"pid: %i, first name: %@, last name: %@", pid, firstName, lastName);
}

執行時在 Console 內會打印出以下文字:
[Session started at 2010-07-20 11:31:39 +0800.]
2010-07-20 11:31:41.545 sqlite[39544:207] Database file found at path /Users/Lawrence/Library/Application Support/iPhone Simulator/4.0/Applications/999BFA7F-6D9B-490A-B542-CDCA79B1590E/Documents/sample.sqlite
2010-07-20 11:31:41.547 sqlite[39544:207] pid: 1, first name: Lawrence, last name: Cheung
2010-07-20 11:31:41.548 sqlite[39544:207] pid: 2, first name: Tom, last name: Chan
2010-07-20 11:31:41.549 sqlite[39544:207] pid: 3, first name: Ken, last name: Choi

應用程式完結時記得要將資料庫連接關閉:
[[DBHelper newInstance] closeDatabase];

文章來源 :
http://pro.ctlok.com/p/about.html

2011年2月23日 星期三

運算加速





位元運算在C’ C++ 等語言中都相當常見,優點運算效率高,缺點可讀性低。如專案中需要以高效能來執行的話,可當你專案完成後再來進行最佳化哦。以下來介紹位元運算加速技巧:

1. 左移運算(Left Shift) = 乘上2 的倍數數值,加速 300%。
   x = x* 2; 
   x = x* 64; 
   //改為: 
   x = x << 1; // 2 = 21 
   x = x << 6; // 64 = 26


2. 右移運算 = 除上 2 的倍數數值,加速 350%。
   x = x/ 2; 
   x = x/ 64; 
   //改為: 
   x = x >> 1; // 2 = 21 
   x = x >> 6; // 64 = 26


3. 數值轉整數加速 10%
   x = int(1.232) 
   //改為: 
   x = 1.232 >> 0;

4. 交換兩個數值(swap),使用 XOR 可以加速 20%
   var t:int = a; 
   a = b; 
   b = t; 
   //equals: 
   a^= b; 
   b^= a; 
   a^= b;

5. 正負號轉換,可以加入 300%
   i = -i; 
   //改為 
   i = ~i+ 1; // NOT 寫法 
   //或 
   i = (i^ -1) + 1; // XOR 寫法

6. 取餘數,如果除數為 2 的倍數,利用 AND 運算加速 600%
   x = 131 % 4; 
   //equals: 
   x = 131 & (4 - 1);

7. 利用 AND 運算檢查整數是否為 2 的倍數,可以加速 600%
   isEven= (i% 2) == 0; 
   //equals: 
   isEven= (i& 1) == 0;

8. 加速 Math.abs 600% 的寫法1,寫法2 又比寫法1加速 20%
   //寫法1 
   i= x< 0 ? -x: x; 
   //寫法2 
   i= (x^ (x>> 31)) - (x>> 31);

9. 比較兩數值相乘之後是否擁有相同的符號,加速 35%
   eqSign= a* b> 0; 
   //equals: 
   eqSign= a^ b> 0;
   其他位元運算技巧 

10. RGB 色彩分離 
   var 24bitColor:uint = 0xff00cc; 
   var r:uint = 24bitColor >> 16; 
   var g:uint = 24bitColor >> 8 & 0xFF; 
   var b:uint = 24bitColor & 0xFF;

11. RGB 色彩合併
   var r:uint = 0xff; 
   var g:uint = 0x00; 
   var b:uint = 0xcc; 
   var 24bitColor:uint = r<< 16 | g<< 8 | b;



參考資料:
[1] Bitwise gems - fast integer math
[2] Bitwise Operations in C

Git 介紹

What Git is ? and what's the difference between git,CVS and SVN ?

http://www.youtube.com/watch?v=74yphulj3uo&feature=related

Local Git Repositry

2011年2月21日 星期一

Git 使用教學

架設好之後,接下來就是測試看看,順便利用 Git 建立 Local Repository,剛開始的目錄 /path/git/prj1 裡面是沒有任何一個 Repository,我們可以利用下面指令建立:
1
2
3
mkdir /path/git/prj1
cd /path/git/prj1
git init
第一次 Commit to Remote Repository,需要底下步驟完成,才可以 clone,你在本機或者是其他機器使用下面步驟都是可以的
1
2
3
4
5
6
7
8
mkdir prj2
cd prj2
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@REMOTE_SERVER:/path/git/prj2
git push origin master
建立好之後,測試看看,Git clone 資料, 資料修改後上傳.(分兩個目錄測試)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 建立兩個測試目錄
mkdir /tmp/a /tmp/b
# 切換到 a 目錄
cd /tmp/a
# 先把遠端 repo 抓下來
git clone http://example.com/path/git/prj2
cd /tmp/b
git clone http://example.com/path/git/prj2
cd php
# 增加 test.php 檔案
echo "test" > test.php
# 新增到 server
git add test.php
# 送出 commit 
git commit -m "add test.php"
# push 到伺服器
git push
#切換 a 目錄
cd /tmp/a/php
# 抓取伺服器上面新檔案 test.php
git pull


首先,開啟一個專案只要輸入


git init


再來,每次修改好了以後,可以先將修改存入stage


git add <modified files>


若一次修改大量檔案,可以將所有檔案修改都add進去stage


git add .


之後commit提交一次的修改


git commit -m "註解"


另外也可以把git add與git commit用一個指令完成


git commit -a -m "註解"


git特別的一點是,他可以在本地端開啟並使用。上面這些用法完全不用伺服器,本機就可以執行。

本地端會有自己的repo,可以在飛機上,各種沒有網路的地方都可以順利使用並提交任何變更。

等您覺得修改好了,可以放上伺服器的時候,確保網路連線並輸入


git push


就可以將這邊的檔案與變更提交到github上面。
如果您在github上的版本較新,也可以輸入


git pull


更新本地端的repo。

如果今天tom的test repo有了新的變更,告訴billy,billy要將變更merge到自己的repo中,可以在本地端輸入


git pull git://github.com/tom/test.git


pull這個指令其實涵蓋了fetch(將變更複製回來)以及merge。
因此經過merge後,tom的變更就加入到billy的repo囉!

另外版本控制系統的branch功能也很有意思,若您的程式碼同時要修改bug,又要加入新功能,可以fork出一個branch,一個專門修bug,一個專門加入新功能,等到穩定後再來merge


git branch bug_fix #建立branch,名為bug_fix
git checkout bug_fix #切換到bug_fix這個branch
git checkout master #換為主要的repo
git merge bug_fix #把bug_fix這個branch和現在的branch合併
git push origin bug_fix:refs/heads/bug_fix #把bug_fix這個branch推至遠端repo上面


若有branch在remote,想要查看並checkout出來


git branch -r #查看遠端branch
git checkout -b bug_fix_local bug_fix_remote #把本機端切換為遠端的bug_fix_remote branch,並命名為bug_fix_local


還有其他可以觀看repo狀態的工具


git log #可以查看每次commit的改變
git diff #可以查看最近一次改變的內容,加上參數可以看其他的改變,並互相比較
git show #可以看某次的變更


若想知道目前repo的狀態,可以輸入


git status



這邊只是一些簡單的功能,還有更多的功能,等大家去摸
想要深入了解git,可以看
http://excess.org/article/2008/07/ogre-git-tutorial/
這個教學影片說明的很詳細。

也有很多小工具,比如這個
http://gugod.org/2008/11/github-badge.html
可以把您目前的github repos顯示在blog上面

希望大家也能在git上面使用github開心的開發!

參考資料
http://github.com/guides/home
http://kylecordes.com/2008/04/30/git-windows-go/
http://nathanj.github.com/gitguide/creating.html
http://www.qweruiop.org/nchcrails/posts/49





http://slobozincur.appspot.com/777bar.blogspot.com/2011/01/git.html