3/04/2011

Git

Git, 大名鼎鼎的分散式版本控制系統, 剛好正值交接空檔期間, 把自學的部份記錄下來

更希望也能幫助路過的人 :)

記得當初第一次知道這工具是前年八月份的時候, 那時剛巧和hychen同家公司, 是他讓我知道這世界有多大...

在OpenSource這條路上, hychen不知領先/努力我多久時間了, 縱使我們走的層次不同

但我一直把他當作是努力和學習的目標 :P

題外話了, 在開始學習Git之前, 我強烈建議一定要讀這本書 :

GIT Pro

個人覺得沒有任何手冊比這本書更詳細了, 閱讀同時, 也可以觀看此影片

一小時搞懂Git

書和影片的作者都是同一人, 在看這影片時, 有版本控制經驗的人會吸收很快.....

像我剛開始看的時候完全沒概念 XD

以前因為鑑於Git的指令繁鎖, 而且又沒靜下心來好好研究...而且之前所屬的公司大部份都是單打獨鬥

也沒有Team work的經驗, 就覺得不需要用到Git這種東西(起初都覺得這應該是Team才會需要)

但這段時間邊研究邊實作, 發現Git不只是版本控制而己, 它能讓你更有效率地工作 !

這些示範都只是對個人專案而言, 如有錯誤請指正 :)

===================

* 建議先略讀Git Pro這本書, 有了大致的概念之後再來實作會較有幫助 *

為了方便理解, 自己隨便建立一個Project :

#mkdir project
#cd project/
#mkdir include
#touch main.c Makefile ; touch include/main.h

在main.c和Makefile添加一些東西吧 !

#include

int main()
{
printf("Hello Git !!\n");
}


all:main.c
gcc -o hello main.c

clean:
rm hello


先來驗證看看吧 :

# make
gcc -o hello main.c
# ./hello
Hello Git !!


好了之後,我們先來看看這個專案有哪些文件 :

# ls -l
總計 20
-rwxr-xr-x 1 dicky dicky 7138 2011-03-04 09:47 hello
drwxr-xr-x 3 dicky dicky 4096 2011-03-04 09:36 include
-rw-r--r-- 1 dicky dicky 65 2011-03-04 09:45 main.c
-rw-r--r-- 1 dicky dicky 50 2011-03-04 09:46 Makefile


假設現在這個專案是公司交待給你的任務, 也是最原始的程式, 當你要摩拳擦掌進行工作時, 用Git來幫你控制及管理你的案子吧 !
首先, 先對整個專案目錄初始化, 並建立Git repository :

# git init
Initialized empty Git repository in /home/dicky/1Work/GIT/project/.git/


這只是建立一個Git Repository, 還需要把你要追蹤的文件加上去 :

# git add .


這個命令會把當前所有文件和目錄都加進去追蹤, 但有些編譯檔和自動執行檔或暫存檔等等,就不需要了
所以新建一個 .gitignore來過濾git追蹤文件 :

#vim .gitignore
*.o
.svn/
hello


這裡面可以用正規表示法, 詳細可以參考Git Pro說明/
接著commit(提交) !

#git commit -a -m 'Initialie Project'
[master (root-commit) 742d723] Initialie Project
Committer: DickyChiang
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

git config --global user.name "Your Name"
git config --global user.email you@example.com

If the identity used for this commit is wrong, you can fix it with:

git commit --amend --author='Your Name '

4 files changed, 13 insertions(+), 0 deletions(-)
create mode 100644 .gitignore
create mode 100644 Makefile
create mode 100755 hello
create mode 100644 main.c


這時看到hello竟然也被提交上去了 ! 看來在add前, 還是先寫好gitignore文件...
不過別擔心, 直接下下面的命令可以把它從stage移除 :

#git rm hello


好了, 使用Git完善我們的專案之後, 接下來可以開工了 !
先建立一個工作分支點,謹記,每個工作分支都是獨立的 ! 當然最後可以合併或再分支 :

#git branch World


這個命令可以幫我們知道現在處於哪一個工作分支點 :

#git branch
World
*master


切換至World的工作分支 :

#git checkout World
Switched to branch 'World'


修改main.c , 增加一個printf :

#vim main.c

#include

int main()
{
printf("Hello Git !!\n");
printf("Hello World !!\n");
}


修改完之後, 可以用status來查看狀態 :

# git status
# On branch World
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: main.c
#
no changes added to commit (use "git add" and/or "git commit -a")


從上面的字看到"Changed but not updated",表示修改了但還沒更新上去
如果你確定所有的文件都修改完了, 可以不用打add , 用commit -a 一次全部更新和提交 :

#git commit -a -m "This is branch World"
[World c9dc0a0] This is branch World
Committer: DickyChiang
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

git config --global user.name "Your Name"
git config --global user.email you@example.com

If the identity used for this commit is wrong, you can fix it with:

git commit --amend --author='Your Name '

1 files changed, 1 insertions(+), 0 deletions(-)


來查看World這個工作分支的結果吧 :

#make
gcc -o hello main.c
#git branch
* World
master
# ./hello
Hello Git !!
Hello World !!


假如現在你的主管或是別的項目負責人,忘了備份或者code改爛等等,請你幫忙download原始image...
如果沒有Git, 想必一定是把之前改的code, 用define註釋掉......再不然就是copy專案在別的地方, 跳到那個目錄再重新compile.....

但Git只要一個動作就能搞定 !!

#git checkout master
Switched to branch 'master'
#make
gcc -o hello main.c
# ./hello
Hello Git !!


等幫完同事的忙, 直接再切換分支就可以繼續工作 ! 不用擔心遺失或者佔用空間
現在你在World的工作分支下己經測試完了, 覺得改的code相當穩定, 這時就可以合併到master上 :

#git merge World
Updating 742d723..c9dc0a0
Fast-forward
main.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)


#make
gcc -o hello main.c
# ./hello
Hello Git !!
Hello World !!


合併完之後, 就可以把先前的分支砍掉, 代表這個工作階段結束 :

#git branch -d World


當然合併不見得都會順利, 因為你的工作分支不見得只有一個, 可能會在現有分支上再分支更多個等等..
所以許多分支修改相同的檔案時, 一旦合併就會出現這樣訊息 :

Auto-merging main.c
CONFLICT (content): Merge conflict in main.c
Automatic merge failed; fix conflicts and then commit the result.

訊息是說, Git己經幫你合併了, 但你需要手動修改檔案容的衝突, 之後完成commit動作

有衝突的內容, Git會幫你區分開來哪行是哪個分支改動的地方,像這樣 :

<<<<<<< HEAD struct Class *pclass; pclass = malloc(sizeof(struct Class)); write(pclass); printf("The student id = %d\n",pclass->id);
printf("The student age = %d\n",pclass->age);
printf("The student name = %s\n",&pclass->name);
free(pclass);
=======
printf("hello world\n");
printf("This is branch ICC53\n");
>>>>>>> ICC53


其中<<<<<<< HEAD代表主分支,也就是mast,而=======就是分隔線,代表以下是另一個分支增加內容
所以自己需要手動幫這些衝突修改掉, 並刪除這些分隔線, 就可以commit了 !

========================

以上這些只是非常簡單的運用, 但我相信處理個人專案足夠了 !

熟悉Git , 你會感受它的強大所在 :)

Wirtten by Dicky

No comments:

Post a Comment