Git 的使用感受


 

Git 的使用感受

從開始工作到現在,在公司里面一直用 svn 來做版本管理。大約半年前聽說了 Git,因為 Git 的光輝相當耀眼,作者是 Linus Torvalds,被大量的開源軟件采用,如 jQuery, Perl, Qt, ROR, YUI, GNOME 等,所以決定學一學。
比較慶幸的是,國內有一本較好的介紹 Git 的書:《Git 權威指南》
我大概花了一個月的周末時間來學習它。在這里總結一下使用 Git 的感受,主要是和 SVN 來做一些比較,以便突出 Git 的特點。

學習成本

首先我感覺 Git 的學習成本還是比較高的。svn 基本上不到 20 個命令就可以應付日常的工作了,而 Git 有上百個命令。我在學習 SVN 的時候,基本上沒有看什么書,最多就是在網上隨便看了一些貼子,就基本會使用 SVN 了。而我花在 Git 的學習時間算下來,至少有 1 周。

因為 Git 的學習成本較高,所以當一個會 svn 的同學剛剛接觸 Git 的時候,如果簡單地把 Git 當 SVN 用,就會感覺 Git 相當難用。我在公司就時常聽到同事抱怨它。所以我認為,要想真正用好 Git,還是需要投入時間來學習它,否則是很難使用的。

Git 的內部結構

Git 真正是一個面向程序員的工具,它的內部數據結構是一個有向無環圖,並且,你必須理解它的內部數據結構后,才能掌握它。因為你的很多操作,都其實對應的是這個有向無環圖的操作。比如:

  • git commit 就是增加一個結點。
  • git commit –amend 就是改發一個結點。
  • git reset 就是修改 HEAD 指向的結點。

另外,Git 內部包括三個區域:工作區,暫存區和版本庫。

  • git add 是將工作區的內容保存到暫存區
  • git checkout 是將暫存區的內容覆蓋工作區
  • git commit 是將暫存區的內容保存到版本庫
  • git reset 默認情況下是將版本庫的內容覆蓋工作區
  • git diff 也有三種情況,分別是比較工作區與暫存區,工作區與版本庫,暫存區與版本庫之間的差別

了解了 Git 的內部結構,對於這些 Git 的命令就更加理解了。

svn 的坑

svn 在平常使用上基本沒什么坑,平時通過
svn pe svn:ignore . 設置好忽略的文件,以免誤把不應該加入版本管理的文件加進來。

我唯一遇到的一次問題是這樣的:我有一個目錄要加入 svn 的版本庫,但是目錄里面的一些文件不想加入。如果直接輸入 svn add 目錄名,就會把目錄下所有文件都加入到版本管理中。如果 cd 到那個目錄里面配置 svn:ignore,又會因為當前目錄還不在版本管理中,設置不了。最后找到的解決辦法是在 svn add 的時候增加 –non-recursive 參數:

svn add dirname --non-recursive
或者是:
$ svn add dirname --depth empty

還有就是對於一些不小心用 svn add 加入了版本管理,但實際上不應該加的目錄。可以這么做:

svn export spool spool-tmp    (這里 export 可以將原目錄中的 .svn 目錄給清除掉)
svn rm spool
svn ci -m 'Removing inadvertently added directory "spool".'
mv spool-tmp spool
svn propset svn:ignore 'spool' .
svn ci -m 'Ignoring a directory called "spool".'

Git 的坑

  • 在 windows 下的文件的權限因為無法和 linux 上完全一致,所以用 Git 檢出的文件權限可能顯示為被更改。
    另外因為 windows 下的換行和 linux 上也不一樣,協作開發時也容易出問題。所以在 windows 上使用 Git 的同學需要加上以下 2 行配置參數:
git config --global core.filemode false
git config --global core.autocrlf true
第一句是忽略文件權限的改動。
第二句是將文件 checkout 時自動把 LF 轉成 CRLF,check in 時自動把 CRLF 轉成 LF
  • svn 的 svn revert filename 對應的其實是 git checkout -- filename, 而 git revert xxx 是基於 xxx 提交所做的改動,做一次反向提交,和 svn revert 完全不一樣。

Git 的一些小技巧

節省clone體積

有些時候,我們只想簡單學習一下項目代碼,這個時候,用 git clone rep_address --depth 1 可以只 clone 每個文件最新的一個提交,這樣速度會快很多。

強制推送

一旦推送到遠程倉庫后,就不要用類似 git resetgit ci --amendgit rebase 等破壞性提交了,否則遠程倉庫會因為你的新推送不是 Fast Forward 而拒絕提交 (關於什么是 Fast Forward 要講的太多了,自已看書吧)。如果實在不小心做了。在確定別人沒有檢出前,用 git push -f 可以強制推送到遠程倉庫中。如下圖:

使用 git svn

在公司沒有應用 git 前,你可以用 git svn 來做管理。 git svn 相關命令:

git svn clone -r REV1:HEAD svn_addr local_addr
git svn dcommit  提交到 SVN
git svn fetch    從 svn up 信息
git svn rebase   將從 svn up 過來的信息,rebase 成 git 提交
git svn rebase --continue  沖突后繼續 rebase 信息

用 git svn clone 的時候,帶上 -r rev1:HEAD 參數,可以省去將 SVN 整個提交歷史抓取下來的時間。

設置常用命令的別名

在用戶的 home 目錄下,有一個 .gitconfig 文件,里面可以配置一些別名,方便平時的 git 操作。
特別是那些平日使用 SVN 的短命令習慣了的同學,配置一下別名后,使用 git 就會相當順手了。我配置的別名如下。這里特別多說一句,有些人喜歡將 ci 設置成 commit -a,這樣就不用 git add 來把需要提交的文件加入到暫存區了。在《Git 權威指南》中,作者極力反對這樣做。因為 Git 本身在提交前有 add 這步,就是為了讓提交者能夠審視自己的提交文件,以防止錯誤的提交發生。

[alias]
    st = status -s
    ci = commit
    l = log --oneline --decorate -13
    ll = log --oneline --decorate
    co = checkout
    br = branch
    rb = rebase
    dci = dcommit

刪除不在 git 管理下的文件

如果你需要刪除 Git 下沒有加入到版本庫中的文件,可以使用:

git clean -nd 測試刪除
git clean -fd 真實刪除

 

搭建自己的遠程倉庫

搭建一個 Git 遠程倉庫相當簡單,直接在一台帶 SSH 的服務器上用 git init –bare dirname 即可。本地可以用 git remote 命令來設置多個遠程分支。另外,第一次提交的時候,因為遠程倉庫中沒有任何分支,需要用如下指令建立 master 分支:

git remote add origin yourname@yourhost.com:~/path/repository_name
git remote add add2 yourname@yourhost.com:~/path/repository_name
git push origin master
git push add2 master
// 如果 git remote add 設置地址寫錯了,可以用 git remote set-url 更改:
git remote set-url origin yourname@yourhost.com:~/path/repository_name

 

如何用 Git 將一個文件的歷史提交恢復?

上次遇到一個問題,我某次提交改動了很多文件,但是其中有一個是不應該改的。所以我需要把這次提交中關於那個文件的改動撤銷。直接用 git checkout 命令可以檢出某一個文件的歷史版本,然后就可以將對這個文件的改動取消了。如下:

git checkout CommitId fileName 
git ci -m "revert a file modification"

本地工作區還有未提交的內容時,不能 pull?

可以先用 git stash 將內容暫存,然后再 pull,成功后再 git stash pop 將修改恢復。

提交的郵箱錯了?

有些時候,因為同時在 github 和公司內部做提交,所以用 2 個不同的郵箱。如果一個新工程 clone 下來,忘了用 git config 來設置提交用戶名和郵箱,就有可能用錯誤的郵箱作為賬號名提交。這個時候,如果你只是錯了最近的一次提交而已,可以用如下命令來將最近的一次提交作者名和郵箱修改:

git config user.email your-email@163.com
git config user.name your-name
git commit --amend --reset-author

如果等你發現的時候,已經錯了很多提交了。可以用如下命令來一次性修改多個提交的用戶名和郵箱:

git filter-branch -f --env-filter "
GIT_AUTHOR_NAME='Tang Qiao'
GIT_AUTHOR_EMAIL='tangqiao@fenbi.com'
GIT_COMMITTER_NAME='Tang Qiao'
GIT_COMMITTER_EMAIL='tangqiao@fenbi.com'
" HEAD

提交的時候自動去掉源碼末尾的空格

源碼末尾的空格幾乎都是無意義的,應該去掉的。大多數 review 系統,都會將源碼末尾的空格標紅。所以,我們何不在提交時讓 git 自動幫我們去掉這些空格呢?這個可以通過設置 git 的 hook 來實現,具體方法如下:

  1. 用 vim 編輯一個名為 pre-commit 的文件:

    vim .git/hooks/pre-commit
  2. 輸入如下代碼,保存退出 vim

#!/bin/sh

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
   against=HEAD
else
   # Initial commit: diff against an empty tree object
   against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -E 's/:[0-9]+:.*//' | uniq` ; do
    # Fix them!
    sed -i '' -E 's/[[:space:]]*$//' "$FILE"
    git add "$FILE"
done
  1. 增加 pre-commit 的運行權根:
    chmod +x .git/hooks/pre-commit

讓常用操作自動帶顏色

默認的 git diff, status, log 什么的都是不帶顏色的,可以用如下命令讓它們都帶上顏色。另外還有一些有趣的命令,一並列在下面。

git config --global --add user.email "email@163.com"
git config --global --add user.name "your name"

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status -s
git config --global alias.l log --oneline --decorate -12 

git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
git config --global merge.tool kdiff3
git config --global meregtool.kdiff3.path "/usr/bin/kdiff3"  
git config --global alias.visual "!gitk"

自動補全 git 命令

  1. 安裝 bash-completion: brew install bash-completion

  2. 按要求把以下代碼增加到 .bash_profile 文件中:

if [ -f `brew --prefix`/etc/bash_completion ]; then
  . `brew --prefix`/etc/bash_completion
fi
  1. 下載 bash-completion 對於 Git 的支持
cd /usr/local/etc/bash_completion.d/
sudo curl -O https://raw.github.com/git/git/master/contrib/completion/git-completion.bash

一些 Git 的資料

  • Git Magic 很通俗的一本介紹 Git 的書,比較短小精煉。
  • Pro Git 全面介紹 Git 的書,非常詳細。
  • 《Git 權威指南》 中國人寫的一本介紹 Git 的書,也非常通俗。我個人主要就是通過這本書來學習 Git 的。
  • Github 基於 Git 的開源網站。在 Github 的托管的項目相當多,著名的有:rails, jquery, node, homebrew, three20, jekyll, jquery-ui, backbone, coffee-script, tornado, redis, underscore, asi-http-request, django。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM