閱讀376 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Git團隊協作使用規範 以及一些常用命令詳解

Git 使用規範

特別提醒:

  • 使用Git過程中,必須通過創建分支進行開發,堅決禁止在主幹分支上直接開發。review的同事有責任檢查其他同事是否遵循分支規範。
  • 在Git中,默認是不會提交空目錄的,如果想提交某個空目錄到版本庫中,需要在該目錄下新建一個 .gitignore 的空白文件,就可以提交了
  • 【代碼回溯注意】把外部文件納入到自己的 Git 分支來的時候一定要記得是先比對,確認所有修改都是自己修改的,然後再納入。不然,容易出現代碼回溯
  • 【代碼回溯注意】多人協作時,不要各自在自己的 Git 分支開發,然後發文件合並。正確的方法應該是開一個遠程分支,然後一起在遠程分支裏協作。不然,容易出現代碼回溯(即別人的代碼被覆蓋的情況)
  • 【代碼回溯注意】每個人提交代碼是一定要 git diff 看提交的東西是不是都是自己修改的。如果有不是自己修改的內容,很可能就是代碼回溯
  • 【代碼回溯注意】review 代碼的時候如果看到有被刪除掉的代碼,一定要確實是否是寫代碼的同事自己刪除的。如果不是,很可能就是代碼回溯


格式:[分支名稱]+message
例如:[www2011072501]前台商品列表按價格排序需求實現。
比如有一個客戶留言功能,被我們拆成了很多子塊,那麼提交注釋如下:

git commit -m "[manage2011072501]完成客戶留言的添加、修改功能" git commit -m "[manage2011072501]完成客戶留言的刪除及手動排序功能" git commit -m "[manage2011072501]完成客戶留言的回複功能" git commit -m "[manage2011072501]把舊客戶留言的功能刪除"


分支合並及上線

步驟 Git 操作
克隆代碼 git clone 遠程代碼
創建分支 git checkout -b branch_name
在分支中開發
review代碼
第一輪測試
添加代碼到分支的暫存區 git add somefile
提交代碼到分支 git commit -m "本次提交的注釋"
切換到主版本 git checkout master
獲取遠程最新代碼 git pull origin master
合並某分支到master分支 git merge branch_name
解決合並時產生的衝突 請參考分支合並時衝突的解決
第二輪測試
準備上線文檔
獲取遠程最新代碼 git pull origin master
推送master分支 git push origin master
通知上線
沒有問題了刪除本地分支 git branch -d branch_name


三種狀態

對於任何一個文件,在 Git 內都隻有三種狀態

中文 英文 含義
已提交 committed 已提交表示該文件已經被安全地保存在本地數據庫中了
已修改 modified 已修改表示修改了某個文件,但還沒有提交保存
已暫存 staged 已暫存表示把已修改的文件放在下次提交時要保存的清單中


目錄     用法
git 目錄     它是 Git 用來保存元數據和對象數據庫的地方。該目錄非常重要,每次克隆鏡像倉庫的時候,實際拷貝的就是這個目錄裏麵的數據。
工作目錄     從項目中取出某個版本的所有文件和目錄,用以開始後續工作的叫做工作目錄。這些文件實際上都是從 git 目錄中的壓縮對象數據庫中提取出來的,接下來就可以在工作目錄中對這些文件進行編輯
暫存區域     所謂的暫存區域隻不過是個簡單的文件,一般都放在 git 目錄中。有時候人們會把這個文件叫做索引文件,不過標準說法還是叫暫存區域。 

基本的 Git 工作流程

1、在工作目錄中修改某些文件。
2、對這些修改了的文件作快照,並保存到暫存區域。 
3、提交更新,將保存在暫存區域的文件快照轉儲到 git 目錄中。

安裝 Git

以下命令安裝的為git 1.7.1

sudo apt-get install -y git-core

配置 Git

以下命令為配置 Git 相關信息,以下兩項必須要配置,會出現在每次提交的信息裏。

git config --global user.name  "caowlong" #規定為姓名全拚
git config --global user.email "caowlong163@163.com" #規定為公司郵箱
git config --global merge.tool "meld"
git config --global color.ui   true # 使用git默認的配色方案,推薦
git config --global --list # 查看配置信息
git config --global user.name # 查看 user.name 的配置信息 

讓 Git 用 meld 比較文件差異

gedit ~/git-meld.sh
#輸入下麵兩行內容保存並退出

#!/bin/sh
meld $2 $5

執行

chmod +x ~/git-meld.sh
git config --global diff.external ~/git-meld.sh

以下為使用示例

git diff readme.txt
git diff --cached readme.txt

獲取幫助

格式 git help <verb>

示例
git help commit # 按 q 退出幫助

取得項目的 Git 倉庫

有兩種取得 Git 項目倉庫的方法

在現存的目錄下,通過導入所有文件來創建新的 Git 倉庫從已有的 Git 倉庫克隆出一個新的鏡像倉庫來
一、從當前目錄初始化

要對現有的某個項目開始用 Git 管理,隻需到此項目所在的目錄,執行

    cd 某個目錄 
    git init

初始化後,在當前目錄下會出現一個名為 .git 的目錄,所有 Git 需要的數據和資源都存放在這個目錄中。
不過目前,僅僅是按照既有的結構框架初始化好了裏邊所有的文件和目錄,但我們還沒有開始跟蹤管理項目中的任何一個文件

命令 含義
git add *.php 把所有的php文件放入暫存區
git add readme.txt 把名為readme.txt的文件放入暫存區
git add dir/ 把名為dir的目錄裏的所有文件放入暫存區
git add * 把當前目錄的所有文件都放入暫存區
git rm --cached dir/ -r 把名為dir的目錄裏的所有文件取消暫存
git rm --cached readme.txt 把名為readme.txt的文件取消暫存
git commit -m '初始化版本庫' 提交代碼到本地倉庫 “初始化版本庫”為本次提交的注釋信息

這樣我們就創建了一個新的 Git 倉庫

二、從現有倉庫克隆

這個適合我們在公司環境下用,我們可以先把某個項目的 Git 倉庫複製一份出來,這就需要用到 git clone 命令。如果你熟悉其他的 VCS 比如 Subversion,你可能已經注意到這裏使用的是 clone 而不是 checkout。
Git 收取的是項目曆史的所有數據(每一個文件的每一個版本),服務器上有的數據克隆之後本地也都有了。實際上,即便服務器的磁盤發生故障,用任何一個克隆出來的客戶端都可以重建服務器上的倉庫,回到當初克隆時的狀態。

命令格式為: git clone [url] [projectName] 如下兩行均為克隆 Ruby 語言的 Git 代碼倉庫 Grit。

    git clone git://github.com/schacon/grit.git # projectName 省略時以 grit 為默認目錄

這會在當前目錄下創建一個名為 “grit” 的目錄,其中內含一個 .git 的目錄,並從同步後的倉庫中拉出所有的數據,取出最新版本的文件拷貝。如果進入這個新建的 grit 目錄,你會看到項目中的所有文件已經在裏邊了,準備好後續的開發和使用。如果希望在克隆的時候,自己定義要新建的項目目錄名稱,可以在上麵的命令最後指定:

    git clone git://github.com/schacon/grit.git mygrit # 以 mygrit 為默認目錄
    cd mygrit 
    git gc

記錄每次更新到倉庫


工作目錄下麵的所有文件的這兩種狀態

已跟蹤 已跟蹤的文件是指本來就被納入版本控製管理的文件,在上次快照中有它們的記錄,工作一段時間後,它們的狀態可能是未更新,已修改或者已放入暫存區。初次克隆某個倉庫時,工作目錄中的所有文件都屬於已跟蹤文件,且狀態為未修改。 未跟蹤 而所有其他文件都屬於未跟蹤文件。它們既沒有上次更新時的快照,也不在當前的暫存區域。比如:一個全新的文件。

在編輯過某些文件之後,Git 將這些文件標為已修改。我們逐步把這些修改過的文件放到暫存區域,然後等最後一次性提交暫存區域的所有文件更新,如此重複。如下圖

 

檢查當前文件狀態

現在我們可以在命令行下回到剛才的git目錄。要確定哪些文件當前處於什麼狀態,可以用 git status 命令

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

新建一個test.txt的文件,再用git status來看

vi test.txt # 按i輸入內容然後 按ESC 按shift+z+z保存並退出 
git status 
# On branch master 
# Untracked files: 
#       (use "git add <file>..." to include in what will be committed) 

#             test.txt 
nothing added to commit but untracked files present (use "git add" to track)

跟蹤新文件

使用命令 git add 開始跟蹤一個新文件,如跟蹤剛才建立的test.txt文件

git add test.txt
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    new file:   test.txt
#
隻要在 “Changes to be committed” 這行下麵的,就說明是已暫存狀態。

暫存已修改文件

我們修改一下剛才grit目錄下已存在的文件,如benchmarks.txt

vim benchmarks.txt # 按i輸入內容然後 按ESC 按shift+z+z保存並退出
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    new file:   test.txt
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    modified:   benchmarks.txt
#

文件 benchmarks.txt 出現在 “Changed but not updated” 這行下麵,說明已跟蹤文件的內容發生了變化,但還沒有放到暫存區。要暫存這次更新,需要運行 git add 命令,這是個多功能命令,根據目標文件的狀態不同,此命令的效果也不同

    可以用它開始跟蹤新文件
    把已跟蹤的文件放到暫存區
    合並時把有衝突的文件標記為已解決狀態 

git add benchmarks.txt
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    modified:   benchmarks.txt
#    new file:   test.txt
#

現在兩個文件都已暫存,下次提交時就會一並記錄到倉庫。

假設此時,你想要在 benchmarks.txt 裏再加一行,重新編輯存盤後,準備好提交。不過稍等一下,再運行 git status 看看:

vim benchmarks.txt
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    modified:   benchmarks.txt
#    new file:   test.txt
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    modified:   benchmarks.txt
#

現在我們發現 benchmarks.txt 文件出現了兩次!一次算未暫存,一次算已暫存,這怎麼可能呢?好吧,實際上 Git 隻不過暫存了你運行 git add 命令時的版本,如果現在提交,那麼提交的是添加注釋前的版本,而非當前工作目錄中的版本。所以,運行了 git add 之後又作了修訂的文件,需要重新運行 git add 把最新版本重新暫存起來:

git add benchmarks.txt
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    modified:   benchmarks.txt
#    new file:   test.txt
#

忽略某些文件
非重點 有興趣的同學可以參考 https://progit.org/book/zh/ch2-2.html

查看已暫存和未暫存的更新
git diff --staged  # 已經暫存起來的文件和上次提交時的快照之間的差異 也可以用 git diff --cached
git diff # 直接使用此命令是 工作目錄中當前文件和暫存區域快照之間的差異

提交更新
現在的暫存區域已經準備妥當可以提交了。在此之前,請一定要確認還有什麼修改過的或新建的文件還沒有 git add 過,否則提交的時候不會記錄這些還沒暫存起來的變化。所以,每次準備提交前,先用 git status 看下,是不是都已暫存起來了,然後再運行提交命令 git commit:
git status
git commit -m "提交備注" # 可以直接提交
這樣我們就完成了一次git提交

 跳過使用暫存區域
不推薦 盡管使用暫存區域的方式可以精心準備要提交的細節,但有時候這麼做略顯繁瑣。Git 提供了一個跳過使用暫存區域的方式,隻要在提交的時候,給 git commit 加上 -a 選項,Git 就會自動把所有已經跟蹤過的文件暫存起來一並提交,從而跳過 git add 步驟:
git commit -a -m "強製提交備注"

移除文件
要從 Git 中移除某個文件,就必須要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),然後提交。可以用 git rm 命令完成此項工作,並連帶從工作目錄中刪除指定的文件,這樣以後就不會出現在未跟蹤文件清單中了。

git rm somefile #
如果刪除之前修改過並且已經放到暫存區域的話,則必須要用強製刪除選項 -f
git rm -f somefile
我們想把文件從 Git 倉庫中刪除(亦即從暫存區域移除),但仍然希望保留在當前工作目錄中。換句話說,僅是從跟蹤清單中刪除。
git rm --cached readme.txt
批量移除
git rm log/\*.log


移動文件
要在 Git 中對文件改名,可以這麼做:
git mv file_from file_to
相當於執行以下的3個命令
mv file_from file_to
git rm file_from
git add file_to
示例如下
git mv test.txt testtest.txt
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    new file:   testtest.txt


查看提交曆史

在提交了若幹更新之後,又或者克隆了某個項目,想回顧下提交曆史,可以使用 git log 命令。

git clone git://github.com/schacon/simplegit-progit.git
cd simplegit-progit/

然後在此項目中運行 git log,應該會看到下麵的輸出:

git log


commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the verison number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test code

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

更多參數說明
參數     說明
-p     按補丁格式顯示每個更新之間的差異。
--stat     顯示每次更新的文件修改統計信息。
--shortstat     隻顯示 --stat 中最後的行數修改添加移除統計。
--name-only     僅在提交信息後顯示已修改的文件清單。
--name-status     顯示新增、修改、刪除的文件清單。
--abbrev-commit     僅顯示 SHA-1 的前幾個字符,而非所有的 40 個字符。
--relative-date     使用較短的相對時間顯示(比如,“2 weeks ago”)。
--grap     顯示 ASCII 圖形表示的分支合並曆史。
--pretty     使用其他格式顯示曆史提交信息。可用的選項包括 oneline,short,full,fuller 和 format(後跟指定格式)。
-n     僅顯示最近的 n 條提交
--since, --after     僅顯示指定時間之後的提交。
--until, --before     僅顯示指定時間之前的提交。
--author     僅顯示指定作者相關的提交。
--committer     僅顯示指定提交者相關的提交。

git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
#如果要查看 Git 倉庫中,2008 年 10 月期間,Junio Hamano 提交的但未合並的測試腳本(位於項目的 t/ 目錄下的文件)
git log --pretty="%h:%s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/ 
選項     說明
%H    提交對象(commit)的完整哈希字串
%h    提交對象的簡短哈希字串
%T    樹對象(tree)的完整哈希字串
%t    樹對象的簡短哈希字串
%P    父對象(parent)的完整哈希字串
%p    父對象的簡短哈希字串
%an    作者(author)的名字
%ae    作者的電子郵件地址
%ad    作者修訂日期(可以用 -date= 選項定製格式)
%ar    作者修訂日期,按多久以前的方式顯示
%cn    提交者(committer)的名字
%ce    提交者的電子郵件地址
%cd    提交日期
%cr    提交日期,按多久以前的方式顯示
%s    提交說明

 撤消操作
修改最後一次提交
有時候我們提交完了才發現漏掉了幾個文件沒有加,或者提交信息寫錯了。想要撤消剛才的提交操作,可以使用 --amend 選項重新提交:
git commit -m 'first'
git add test.txt
git commit --amend -m 'first too'

 取消已經暫存的文件
git reset HEAD filename

取消對文件的修改
這裏指未git add到的暫存區的文件
在用這條命令前,請務必確定真的不再需要保留剛才的修改。
git checkout -- filename

遠程倉庫的使用
同他人協作開發某個項目時,需要管理這些遠程倉庫,以便推送或拉取數據,分享各自的工作進展。管理遠程倉庫的工作,包括添加遠程庫,移除廢棄的遠程庫,管理各式遠程庫分支,定義是否跟蹤這些分支,等等。

查看當前的遠程庫
使用git remote 查看當前配置有哪些遠程倉庫,至少可以看到一個名為 origin 的遠程庫,Git 默認使用這個名字來標識你所克隆的原始倉庫:
git clone git://github.com/schacon/ticgit.git
cd ticgit
git remote # 列出每個遠程庫的簡短名字
  origin
git remote -v # 顯示對應的克隆地址
  origin    git://github.com/schacon/ticgit.git (fetch)
  origin    git://github.com/schacon/ticgit.git (push)

 添加遠程倉庫
要添加一個新的遠程倉庫,可以指定一個簡單的名字,以便將來引用格式:git remote add [shortname] [url]:
cd ticgit/
git remote -v
  origin    git://github.com/schacon/ticgit.git (fetch)
  origin    git://github.com/schacon/ticgit.git (pus
git remote add pb git://github.com/paulboone/ticgit.git
git remote -v
  origin    git://github.com/schacon/ticgit.git (fetch)
  origin    git://github.com/schacon/ticgit.git (push)
  pb    git://github.com/paulboone/ticgit.git (fetch)
  pb    git://github.com/paulboone/ticgit.git (push)
現在可以用字串 pb 指代對應的倉庫地址了
git fetch pb
  remote: Counting objects: 58, done.
  remote: Compressing objects: 100% (24/24), done.
  remote: Total 44 (delta 23), reused 38 (delta 17)
  Unpacking objects: 100% (44/44), done.
  From git://github.com/paulboone/ticgit
   * [new branch]      master     -> pb/master
   * [new branch]      ticgit     -> pb/ticgit

 從遠程倉庫抓取數據
命令 git pull [remote-name]
此命令會到遠程倉庫中拉取所有你本地倉庫中還沒有的數據。運行完成後,你就可以在本地訪問該遠程倉庫中的所有分支,將其中某個分支合並到本地,或者隻是取出某個分支
如果是克隆了一個倉庫,此命令會自動將遠程倉庫歸於 origin 名下。所以,git pull origin 會抓取從你上次克隆以來別人上傳到此遠程倉庫中的所有更新(或是上次 pull 以來別人提交的更新)。有一點很重要,需要記住,pull 命令隻是將遠端的數據拉到本地倉庫,並不自動合並到當前工作分支,隻有當你確實準備好了,才能手工合並。

推送數據到遠程倉庫
項目進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的數據推送到遠程倉庫。實現這個任務的命令很簡單: git push [remote-name] [branch-name]。如果要把本地的 master 分支推送到 origin 服務器上(再次說明下,克隆操作會自動使用默認的 master 和 origin 名字),可以運行下麵的命令:
git push origin master
隻有在所克隆的服務器上有寫權限,或者同一時刻沒有其他人在推數據,這條命令才會如期完成任務。如果在你推數據前,已經有其他人推送了若幹更新,那你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,並到自己的項目中,然後才可以再次推送。


遠程倉庫的刪除和重命名

在新版 Git 中可以用 git remote rename 命令修改某個遠程倉庫的簡短名稱,比如想把 pb 改成 paul,可以這麼運行:
git remote rename pb paul
git remote
  origin
  paul

移除遠程倉庫
git remote rm paul
git remote
  origin

最後更新:2017-04-03 18:51:58

  上一篇:go A Visual Git Reference
  下一篇:go DOM4J解析XML