git 簡要總結

基本概念

  • 工做區(working Directory)就是你在電腦裏能看到的目錄php

  • 版本庫(repository) 工做區有一個隱藏目錄.git,這個不算工做區,是版本庫python

  • 暫存區 Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區git

  • master 還有Git爲咱們自動建立的第一個分支mastergithub

  • HEAD 指向master的一個指針叫HEADshell

咱們把文件往Git版本庫裏添加的時候,是分兩步執行的:
第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。由於咱們建立Git版本庫時,Git自動爲咱們建立了惟一一個master分支,因此,如今,git commit就是往master分支上提交更改。能夠簡單理解爲,須要提交的文件修改統統放到暫存區,而後,一次性提交暫存區的全部修改編程

安裝git

mac上ubuntu

  1. 安裝brewvim

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  2. 安裝gitapi

➜  ~ brew install git
#若出現下面的狀況表示安裝成功
➜  ~ git --version
git version 2.10.1

ubuntu上ruby

root@fan:~# sudo apt-get install git
sudo: 沒法解析主機:fan
正在讀取軟件包列表... 完成
正在分析軟件包的依賴關係樹
正在讀取狀態信息... 完成
git 已是最新版 (1:2.7.4-0ubuntu1)。
升級了 0 個軟件包,新安裝了 0 個軟件包,要卸載 0 個軟件包,有 0 個軟件包未被升級。

安裝成功後還須要配置git

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
#配置別名
git config --global alias.st status #查看狀態
git config --global alias.co checkout 
git config --global alias.ci commit #提交
git config --global alias.br branch #分支
git config --global alias.unstage 'reset HEAD --' 
git config --global alias.last 'log -1 HEAD'
git config --global alias.clog "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global alias.llog "log -graph --pretty=oneline --abbrev-commit"

還能夠設置編輯器

git config --global core.editor vim

建立本地版本庫

  • 建立裸倉庫 git --base init

sh-3.2# pwd
/Applications/XAMPP/htdocs
sh-3.2# mkdir learngit
sh-3.2# cd learngit/
sh-3.2# #初始化目錄爲git能夠管理的倉庫
sh-3.2# git init
Initialized empty Git repository in /Applications/XAMPP/xamppfiles/htdocs/learngit/.git/

查看當前目錄下會多了一個.git目錄

sh-3.2# ls -ah
.    ..    .git

在這時最好先建好.gitignore 文件而後在commit,或者克隆遠程倉庫前,確保遠程倉庫.gitignore文件正確

遠程倉庫的管理和使用

克隆遠程倉庫

一次 Git 克隆會創建你本身的本地分支 master 和遠程分支 origin/master,它們都指向 origin/master 分支的最後一次提交
克隆操做會默認使用的 master做爲分支名 和 origin遠程庫名

git clone [url] 或者 git clone [url] + 要克隆到哪一個目錄

$ git clone git://github.com/schacon/grit.git
$ git clone git://github.com/schacon/grit.git mygrit

添加遠程倉庫

  • git remote add [shortname] [url] 添加新的遠程倉庫

  • git remote 查看當前配置中每一個遠程庫的簡短名稱

    1. git remote -v顯示克隆地址

  • git pull 命令自動抓取數據下來,而後將遠端分支自動合併到本地倉庫中當前分支

  • git fetch [shortname] 要抓取全部遠程倉庫有的,但本地倉庫的遠程分支沒有的信息。若是是克隆了一個倉庫,此命令會抓取從你上次克隆以來別人上傳到此遠程倉庫中的全部更新。
    fetch 命令只是將遠端的數據拉到本地倉庫的遠程分支,並不自動合併到當前工做分支,只有當你確實準備好了,才能手工合併

$ git fetch origin
remote: Counting objects: 20, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (15/15), done.
From git@github.com:schacon/simplegit
 * [new branch]      serverfix    -> origin/serverfix

在 fetch 操做下載好新的遠程分支以後,你仍然沒法在本地編輯該遠程倉庫中的分支。換句話說,在本例中,你不會有一個新的serverfix 分支,有的只是一個你沒法移動的 origin/serverfix 指針
若是要把該內容合併到當前分支,能夠運行 git merge origin/serverfix。若是想要一份本身的 serverfix 來開發,能夠在遠程分支的基礎上分化出一個新的分支來:

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"

這會切換到新建的 serverfix 本地分支,其內容同遠程分支 origin/serverfix 一致,這樣你就能夠在裏面繼續開發了。

舉例

root@fan:/home/wwwroot/git# git init
    初始化空的 Git 倉庫於 /home/wwwroot/git/.git/
    root@fan:/home/wwwroot/git# git status
    位於分支 master
    
    初始提交
    
    無文件要提交(建立/拷貝文件並使用 "git add" 創建跟蹤)
    root@fan:/home/wwwroot/git# git remote add demo git@git.coding.net:fan_code/ceshi2.git
    root@fan:/home/wwwroot/git# git remote
    demo
    root@fan:/home/wwwroot/git# git remote -v
    demo    git@git.coding.net:fan_code/ceshi2.git (fetch)
    demo    git@git.coding.net:fan_code/ceshi2.git (push)
    root@fan:/home/wwwroot/git# git fetch demo 
    remote: Counting objects: 7993, done.
    remote: Compressing objects: 100% (4985/4985), done.
    remote: Total 7993 (delta 2470), reused 7993 (delta 2470)
    接收對象中: 100% (7993/7993), 7.59 MiB | 337.00 KiB/s, 完成.
    處理 delta 中: 100% (2470/2470), 完成.
    來自 git.coding.net:fan_code/ceshi2
     * [新分支]          master     -> demo/master

如今,遠程倉庫[shortname]的主幹分支(master)已經徹底能夠在本地訪問了,對應的名字是 demo/master,你能夠將它合併到本身的某個分支,或者切換到這個分支,看看有些什麼有趣的更新。

修改遠程倉庫地址

Git 倉庫地址修改辦法 git remote set-url origin [NEW_URL]

推送數據到遠程倉庫

  • git push [remote-name] [branch-name]

例如:把本地的 master 分支推送到origin 服務器上

$ git push origin master

把本地的 master 分支推送到 origin 上並更名爲 test

$ git push origin master:test

查看遠程倉庫信息

  • git remote show [remote-name] 查看某個遠程倉庫的詳細信息

舉例

$ git remote show origin
* remote origin
  URL: git@github.com:defunkt/github.git
  Remote branch merged with 'git pull' while on branch issues
    issues
  Remote branch merged with 'git pull' while on branch master
    master
  New remote branches (next fetch will store in remotes/origin)
    caching
  Stale tracking branches (use 'git remote prune')
    libwalker
    walker2
  Tracked remote branches
    acl
    apiv2
    dashboard2
    issues
    master
    postgres
  Local branch pushed with 'git push'
    master:master

它告訴咱們,運行 git push 時缺省推送的分支是什麼(譯註:最後兩行)。它還顯示了有哪些遠端分支尚未同步到本地(譯註:第六行的caching 分支),哪些已同步到本地的遠端分支在遠端服務器上已被刪除(譯註:Stale tracking branches 下面的兩個分支),以及運行git pull 時將自動合併哪些分支(譯註:前四行中列出的 issues 和 master 分支)。

遠程倉庫的移除和重命名

  • git remote rename 原名 新名

  • git remote rm 遠程倉庫別名 碰到遠端倉庫服務器遷移,或者原來的克隆鏡像再也不使用,又或者某個參與者再也不貢獻代碼,那麼須要移除對應的遠端倉庫,能夠運行

文件管理

將已被git跟蹤的文件移除跟蹤

另一種狀況是,咱們想把文件從Git倉庫中刪除(亦即從暫存區域移除),但仍然但願保留在當前工做目錄中。換句話說,僅是從跟蹤清單中刪除。好比一些大型日誌文件或者一堆.a 編譯文件,不當心歸入倉庫後,要移除跟蹤但不刪除文件,以便稍後在 .gitignore 文件中補上,用 --cached 選項便可:

$ git rm --cached readme.txt

刪除文件

後面能夠列出文件或者目錄的名字,也可使用 glob 模式。比方說:

$ git rm log/\*.log

注意到星號*以前的反斜槓,由於Git有它本身的文件模式擴展匹配方式,因此咱們不用shell來幫忙展開(譯註:實際上不加反斜槓也能夠運行,只不過按照shell擴展的話,僅僅刪除指定目錄下的文件而不會遞歸匹配。上面的例子原本就指定了目錄,因此效果等同,但下面的例子就會用遞歸方式匹配,因此必須加反斜 槓。)。此命令刪除全部log/ 目錄下擴展名爲 .log 的文件。相似的好比:

$ git rm \*~

會遞歸刪除當前目錄及其子目錄中全部 ~ 結尾的文件。

移動文件

不像其餘的VCS系統,Git並不跟蹤文件移動操做。若是在Git中重命名了某個文件,倉庫中存儲的元數據並不會體現出這是一次更名操做。不過Git很是聰明,它會推斷出究竟發生了什麼,至於具體是如何作到的,咱們稍後再談。

既然如此,當你看到 Git 的 mv 命令時必定會困惑不已。要在 Git 中對文件更名,能夠這麼作:

$ git mv file_from file_to

它會恰如預期般正常工做。實際上,即使此時查看狀態信息,也會明白無誤地看到關於重命名操做的說明:

$ git mv README.txt README
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
#   (use "git reset HEAD 
    
    ..." to unstage)
#
#       renamed:    README.txt -> README
#

其實,運行 git mv 就至關於運行了下面三條命令:

$ mv README.txt README
$ git rm README.txt
$ git add README

如此分開操做,Git也會意識到這是一次更名,因此無論何種方式都同樣。固然,直接用 git mv 輕便得多,不過有時候用其餘工具批處理更名的話,要記得在提交前刪除老的文件名,再添加新的文件名。

文件對比

  • git diff
    比較工做區和暫存區文件差別

  • git diff --staged/--cached
    比較暫存區和版本庫文件差別

  • git diff HEAD 能夠查看工做區和版本庫裏面最新版本的區別

  • git diff HEAD -- 文件名 能夠查看指定文件工做區和版本庫裏面最新版本的區別

    舉例

    root@fan:/home/wwwroot/Demo# vim t2
    root@fan:/home/wwwroot/Demo# git diff
    diff --git a/t2 b/t2
    index 9bc7ad0..2672a75 100644
    --- a/t2
    +++ b/t2
    @@ -1 +1,2 @@
     t2
    +t2
    root@fan:/home/wwwroot/Demo# git add t2
    root@fan:/home/wwwroot/Demo# git diff 
    root@fan:/home/wwwroot/Demo# git diff --staged 
    diff --git a/t2 b/t2
    index 9bc7ad0..2672a75 100644
    --- a/t2
    +++ b/t2
    @@ -1 +1,2 @@
     t2
    +t2
    root@fan:/home/wwwroot/Demo# git commit -m '+t2'
    [master 8a74487] +t2
     1 file changed, 1 insertion(+)
    root@fan:/home/wwwroot/Demo# git status
    位於分支 master
    您的分支領先 'origin/master' 共 5 個提交。
      (使用 "git push" 來發布您的本地提交)
    無文件要提交,乾淨的工做區
    root@fan:/home/wwwroot/Demo# git diff
    root@fan:/home/wwwroot/Demo# git diff --staged

提交歷史

查看

git log 有許多選項能夠幫助你搜尋感興趣的提交,接下來咱們介紹些最經常使用的。

咱們經常使用 -p 選項展開顯示每次提交的內容差別,

  • -2 則僅顯示最近的兩次更新:

$ git log -p -2
  • --stat,僅顯示簡要的增改行數統計

$ git log --stat
  • --pretty 選項

    能夠指定使用徹底不一樣於默認格式的方式展現提交歷史。好比用oneline將每一個提交放在一行顯示,這在提交數很大時很是有用**
$ git log --pretty=oneline
edde8f5624c75017e81004b221d2a70e5ed31092 update README.md
75cc8c7ad7cf14f6eaded270c6b472b0b18accbd Initial commit
  • 還能夠用oneline結合--graph選項

    顯示ASCII圖形表示的分支合併歷史,形象地展現了每一個提交所在的分支及其分化衍合狀況, `--abbrev-commit` 僅顯示sha-1前幾個字符,而非全部字符**
$ git log --graph --pretty=oneline --abbrev-commit
*   6be44b4 merge dev
|\  
| * d081be9 I am dev
* | c65bc40 I am master
|/  
* aaa7a54 初始化
  • format

    能夠定製要顯示的記錄格式,這樣的輸出便於後期編程提取分析
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 11 months ago : changed the version number
085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
a11bef0 - Scott Chacon, 11 months ago : first commit

格式佔位符說明

選項     說明
%H    提交對象(commit)的完整哈希字串
%h    提交對象的簡短哈希字串
%T    樹對象(tree)的完整哈希字串
%t    樹對象的簡短哈希字串
%P    父對象(parent)的完整哈希字串
%p    父對象的簡短哈希字串
%an    做者(author)的名字
%ae    做者的電子郵件地址
%ad    做者修訂日期(能夠用 -date= 選項定製格式)
%ar    做者修訂日期,按多久之前的方式顯示
%cn    提交者(committer)的名字
%ce    提交者的電子郵件地址
%cd    提交日期
%cr    提交日期,按多久之前的方式顯示
%s    提交說明
  • git log 支持的其餘命令選項

選項 說明
-p 按補丁格式顯示每一個更新之間的差別。
--stat 顯示每次更新的文件修改統計信息。
--shortstat 只顯示 --stat 中最後的行數修改添加移除統計。
--name-only 僅在提交信息後顯示已修改的文件清單。
--name-status 顯示新增、修改、刪除的文件清單。
--abbrev-commit 僅顯示 SHA-1 的前幾個字符,而非全部的 40 個字符。
--relative-date 使用較短的相對時間顯示(好比,「2 weeks ago」)。
--graph 顯示 ASCII 圖形表示的分支合併歷史。
--pretty 使用其餘格式顯示歷史提交信息。可用的選項包括 oneline,short,full,fuller 和 format(後跟指定格式)。
  • 過濾log輸出

選項 說明

-(n)    僅顯示最近的 n 條提交
--since, --after 僅顯示指定時間以後的提交。
--until, --before 僅顯示指定時間以前的提交。
--author 僅顯示指定做者相關的提交。
--committer 僅顯示指定提交者相關的提交。

例如

$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01"  --before="2008-11-01" --no-merges -- t/

修改最後一次提交

有時候咱們提交完了才發現漏掉了幾個文件沒有加,或者提交信息寫錯了。想要撤消剛纔的提交操做,可使用--amend選項從新提交:啓動文本編輯器後,會看到上次提交時的說明,編輯它確認沒問題後保存退出,就會使用新的提交說明覆蓋剛纔失誤的提交。

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

上面的三條命令最終只是產生一個提交,第二個提交命令修正了第一個的提交內容。

例如:本機mac舉例

root@fan:/home/wwwroot/Demo# vim README.md 
root@fan:/home/wwwroot/Demo# vim test.md 
root@fan:/home/wwwroot/Demo# git log --pretty=oneline --abbrev-commit -2
097860c one
90a8fec phpstorm idea
root@fan:/home/wwwroot/Demo# git add README.md 
root@fan:/home/wwwroot/Demo# git commit -m 'two'
[master 490cf35] two
 1 file changed, 1 insertion(+)
root@fan:/home/wwwroot/Demo# git status
位於分支 master
您的分支領先 'origin/master' 共 2 個提交。
  (使用 "git push" 來發布您的本地提交)
還沒有暫存以備提交的變動:
  (使用 "git add <文件>..." 更新要提交的內容)
  (使用 "git checkout -- <文件>..." 丟棄工做區的改動)
    修改:     test.md
修改還沒有加入提交(使用 "git add" 和/或 "git commit -a")
root@fan:/home/wwwroot/Demo# git add test.md 
root@fan:/home/wwwroot/Demo# git log --pretty=oneline --abbrev-commit -2
490cf35 two
097860c one
root@fan:/home/wwwroot/Demo# git commit --amend 
[master 372f01e] ootwo
 Date: Tue Dec 6 20:13:35 2016 +0800
 2 files changed, 2 insertions(+)
root@fan:/home/wwwroot/Demo# git log --pretty=oneline --abbrev-commit -2
372f01e ootwo
097860c one

git 各類撤銷操做

版本回退

說明

相似3628164...882e1e0的是commit_id(版本號),和SVN不同,Git的commit_id不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個很是大的數字,用十六進制表示,並且你看到的commit_id和個人確定不同,以你本身的爲準。爲何commit_id須要用這麼一大串數字表示呢?由於Git是分佈式的版本控制系統,後面咱們還要研究多人在同一個版本庫裏工做,若是你們都用1,2,3……做爲版本號,那確定就衝突了。

每提交一個新版本,實際上Git就會把它們自動串成一條時間線。若是使用可視化工具查看Git歷史,就能夠更清楚地看到提交歷史的時間線

root@fan:/home/wwwroot/Demo# git log --pretty=oneline
8a744873ac755647767abd149adef2e86ae53d71 +t2
97a15f36b57f6a0c588a058f654901ebeab6de31 +t1
ec30b4cb269ca10560b9abfe203fdd7a5abc7cfb 初始化
  • HEAD指向的版本就是當前版本,HEAD^指的是上一個版本,HEAD^^指的是上上個版本。所以,Git容許咱們在版本的歷史之間穿梭,使用命令git reset --hard commit_id。commit id版本號不必寫全,前幾位就能夠了,Git會自動去找

  • 穿梭前,用git log能夠查看提交歷史,以便肯定要回退到哪一個版本。要重返將來,用git reflog查看命令提交歷史,以便肯定要回到將來的哪一個版本

    舉例

    root@fan:/home/wwwroot/Demo# git log --pretty=oneline --abbrev-commit 
    8a74487 +t2
    97a15f3 +t1
    ec30b4c 初始化
    root@fan:/home/wwwroot/Demo# git reset --hard HEAD^
    HEAD 如今位於 97a15f3 +t1
    root@fan:/home/wwwroot/Demo# git log --pretty=oneline --abbrev-commit 
    97a15f3 +t1
    ec30b4c 初始化
    root@fan:/home/wwwroot/Demo# git reflog
    97a15f3 HEAD@{0}: reset: moving to HEAD^
    8a74487 HEAD@{1}: commit: +t2
    97a15f3 HEAD@{2}: commit: +t1
    ec30b4c HEAD@{3}: commit: 初始化
    root@fan:/home/wwwroot/Demo# git reset --hard 8a74487
    HEAD 如今位於 8a74487 +t2
    root@fan:/home/wwwroot/Demo# git log --pretty=oneline --abbrev-commit 
    8a74487 +t2
    97a15f3 +t1
    ec30b4c 初始化
    root@fan:/home/wwwroot/Demo# git reflog
    8a74487 HEAD@{0}: reset: moving to 8a74487
    97a15f3 HEAD@{1}: reset: moving to HEAD^
    8a74487 HEAD@{2}: commit: +t2
    97a15f3 HEAD@{3}: commit: +t1
    ec30b4c HEAD@{4}: commit: 初始化

撤銷文件修改

假如如今工做區,暫存區某個文件爲版本2,版本庫爲版本1,修改工做區文件後,工做區變爲版本3,運行命令git reset HAED file ,暫存區變爲版本1,跟版本庫一致,而工做區的版本還爲版本3

  • 場景1:使用git checkout — readme.txt丟棄工做區修改

    當你改亂了工做區某個文件的內容,想直接丟棄工做區的修改時,用命令git checkout -- file。命令git checkout — readme.txt

    把readme.txt文件在工做區的修改所有撤銷,這裏有兩種狀況:一種是readme.txt自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;

    一種是readme.txt已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。

    總之,就是讓這個文件回到最近一次git commitgit add時的狀態。

  • 場景2:使用git reset HEAD file丟棄暫存區修改

    當你不但改亂了工做區某個文件的內容,還添加到了暫存區時,添加完以後又修改了工做區,想丟棄暫存區的修改,分兩步,

    1. 第一步用命令git reset HEAD file

    用命令git reset HEAD file能夠把暫存區的修改撤銷掉(unstage),而工做區的文件沒有變化

    就回到了場景1,

    1. 第二步按場景1操做。

  • 場景3:版本回退

    已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退,不過前提是沒有推送到遠程庫。

標籤管理

新建

  • git tag <name>用於新建一個標籤,默認標籤是打在最新提交的commit上,也能夠指定一個commit id;

  • git tag -a <tagname> -m "blablabla..."能夠指定標籤信息;

  • git tag -s <tagname> -m "blablabla..."能夠用PGP簽名標籤;

查看

  • git tag能夠查看全部標籤,git show <tagname> 查看標籤所指向的提交

    例子

    root@fan:/home/wwwroot/git/demo# git status
    位於分支 master
    無文件要提交,乾淨的工做區
    root@fan:/home/wwwroot/git/demo# git reflog
    7aca999 HEAD@{0}: commit: c
    a8e8e16 HEAD@{1}: commit: b
    9cab6a8 HEAD@{2}: commit (initial): a
    root@fan:/home/wwwroot/git/demo# clear
    
    root@fan:/home/wwwroot/git/demo# git tag 'cc'
    root@fan:/home/wwwroot/git/demo# git tag
    cc
    root@fan:/home/wwwroot/git/demo# git reflog
    7aca999 HEAD@{0}: commit: c
    a8e8e16 HEAD@{1}: commit: b
    9cab6a8 HEAD@{2}: commit (initial): a
    root@fan:/home/wwwroot/git/demo# git show cc
    commit 7aca999821cd3384d634a7985782e8816d851d9b
    Author: fan <fan@qq.com>
    Date:   Wed Dec 7 21:08:35 2016 +0800
    
        c
    
    diff --git a/c b/c
    new file mode 100644
    index 0000000..f2ad6c7
    --- /dev/null
    +++ b/c
    @@ -0,0 +1 @@
    +c
    root@fan:/home/wwwroot/git/demo# git tag -a bb -m 'bbbbb' a8e8e16
    root@fan:/home/wwwroot/git/demo# git tag
    bb
    cc
    root@fan:/home/wwwroot/git/demo# git show bb
    tag bb
    Tagger: fan <fan@qq.com>
    Date:   Wed Dec 7 21:09:52 2016 +0800
    
    bbbbb
    
    commit a8e8e16567a8c9adf06fe2778ee647250425451d
    Author: fan <fan@qq.com>
    Date:   Wed Dec 7 21:07:53 2016 +0800
    
        b
    
    diff --git a/b b/b
    new file mode 100644
    index 0000000..6178079
    --- /dev/null
    +++ b/b
    @@ -0,0 +1 @@
    +b

推送標籤到服務器

  • 推送單個標籤git push origin <tagname>

  • 推送全部標籤git push origin --tags

刪除服務器標籤

  1. 首先刪除本地標籤git tag -d [tagname]

  2. 刪除服務器上標籤git push origin :refs/tags/[tagname]

    例子

    root@fan:/home/wwwroot/git/Demo# git pull
    Already up-to-date.
    root@fan:/home/wwwroot/git/Demo# git push origin --tags 
    Total 0 (delta 0), reused 0 (delta 0)
    To git@git.coding.net:fan_code/Demo.git
     * [new tag]         1 -> 1
     * [new tag]         2 -> 2
    root@fan:/home/wwwroot/git/Demo# git tag -d 1
    已刪除標籤 '1'(曾爲 90a8fec)
    root@fan:/home/wwwroot/git/Demo# git tag
    2
    root@fan:/home/wwwroot/git/Demo# git push origin :refs/tags/1
    To git@git.coding.net:fan_code/Demo.git
    - [deleted]         1

分支管理

工做場景

假設此時,你忽然接到一個電話說有個很嚴重的問題須要緊急修補,那麼能夠按照下面的方式處理:

  1. 返回到原先已經發布到生產服務器上的分支。

  2. 爲此次緊急修補創建一個新分支,並在其中修復問題。

  3. 經過測試後,回到生產服務器所在的分支,將修補分支合併進來,而後再推送到生產服務器上。

  4. 切換到以前實現新需求的分支,繼續工做。在切換回來以後,應該也把當前分支的bug修復

查看分支 git branch [name]

  • [name] 是添加分支

  • -d [name] 刪除乾淨的分支(假如分支中包含還沒有合併進來的工做成果,則爲不乾淨的分支)

  • -D [name] 強制刪除

  • -v 查看各個分支最後一個提交對象的信息

  • --merged 查看哪些分支已被併入當前分支(也就是說哪些分支是當前分支的直接上游,若是有分支內容與當前分支內容一致,也會顯示)

  • --no-merged 查看哪些分支未被併入當前分支

切換分支 git checkout [name]

git checkout master

它把 HEAD 指針移回到 master 分支,並把工做目錄中的文件換成了 master 分支所指向的快照內容

建立並切換分支 git checkout -b [name]

合併分支到當前工做分支 git merge [被合併的分支]

分支合併分爲:直接祖先合併、非直接祖先合併(會進行三方合併)

  1. 直接祖先合併

    • 合併時出現了「Fast forward」的提示。因爲當前 master 分支所在的提交對象是要併入的 hotfix 分支的直接上游,Git 只需把master 分支指針直接右移。換句話說,若是順着一個分支走下去能夠到達另外一個分支的話,那麼 Git 在合併二者時,只會簡單地把指針右移,由於這種單線的歷史分支不存在任何須要解決的分歧,因此這種合併過程能夠稱爲快進(Fast forward)。

  2. 非直接祖先合併(合併mster-c4和iss53->c5)

      1. 此次你的開發歷史是從更早的地方開始分叉的。因爲當前 master 分支所指向的提交對象(C4)並非 iss53 分支的直接祖先,Git 不得不進行一些額外處理。就此例而言,Git 會用兩個分支的末端(C4 和 C5)以及它們的共同祖先(C2)進行一次簡單的三方合併計算。此次,Git 沒有簡單地把分支指針右移,而是對三方合併後的結果從新作一個新的快照,並自動建立一個指向它的提交對象(C6)。這個提交對象比較特殊,它有兩個祖先(C4 和 C5)。

刪除分支 git branch -d [name]

推送全部分支到遠程倉庫origin git push origin --all

root@fan:/home/wwwroot/git/Demo# git push origin --all
對象計數中: 3, 完成.
壓縮對象中: 100% (3/3), 完成.
寫入對象中: 100% (3/3), 280 bytes | 0 bytes/s, 完成.
Total 3 (delta 2), reused 0 (delta 0)
To git@git.coding.net:fan_code/Demo.git
 * [new branch]      dev -> dev
 * [new branch]      dev2 -> dev2
 * [new branch]      test -> test

長期分支

因爲 Git 使用簡單的三方合併,因此就算在較長一段時間內,反覆屢次把某個分支合併到另外一分支,也不是什麼難事。也就是說,你能夠同時擁有多個開放的分支,每一個分支用於完成特定的任務,隨着開發的推動,你能夠隨時把某個特性分支的成果併到其餘分支中。

特性分支

在任何規模的項目中均可以使用特性(Topic)分支。一個特性分支是指一個短時間的,用來實現單一特性或與其相關工做的分支。可能你在之前的版本控 制系統裏從未作過相似這樣的事情,由於一般建立與合併分支消耗太大。然而在 Git 中,一天以內創建、使用、合併再刪除多個分支是常見的事。

遠程分支

遠程分支(remote branch)是對遠程倉庫中的分支的索引。它們是一些沒法移動的本地分支;只有在 Git 進行網絡交互時纔會更新。
咱們用 (遠程倉庫名)/(分支名) 這樣的形式表示遠程分支
一次 Git 克隆會創建你本身的本地分支 master 和遠程分支 origin/master,它們都指向 origin/master 分支的最後一次提交

跟蹤遠程分支

從遠程分支 checkout 出來的本地分支,稱爲_跟蹤分支(tracking branch)_。跟蹤分支是一種和遠程分支有直接聯繫的本地分支。在跟蹤分支裏輸入git push,Git 會自行推斷應該向哪一個服務器的哪一個分支推送數據。反過來,在這些分支裏運行 git pull 會獲取全部遠程索引,並把它們的數據都合併到本地分支中來。

在克隆倉庫時,Git 一般會自動建立一個名爲 master 的分支來跟蹤 origin/master。這正是git push 和 git pull 一開始就能正常工做的緣由。固然,你能夠爲所欲爲地設定爲其它跟蹤分支,好比origin 上除了 master 以外的其它分支。剛纔咱們已經看到了這樣的一個例子:git checkout -b [分支名] [遠程名]/[分支名]。若是你有 1.6.2 以上版本的 Git,還能夠用--track 選項簡化:

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"

要爲本地分支設定不一樣於遠程分支的名字,只需在前個版本的命令裏換個名字:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "sf"

如今你的本地分支 sf 會自動向 origin/serverfix 推送和抓取數據了。

刪除遠程分支

若是再也不須要某個遠程分支了,好比搞定了某個特性並把它合併進了遠程的 master 分支(或任何其餘存放穩定代碼的地方),能夠用這個很是無厘頭的語法來刪除它:git push [遠程名] :[分支名]。若是想在服務器上刪除serverfix 分支,運行下面的命令:

$ git push origin :serverfix
To git@github.com:schacon/simplegit.git
 - [deleted]         serverfix

有種方便記憶這條命令的方法:記住咱們不久前見過的 git push [遠程名] [本地分支]:[遠程分支] 語法,若是省略 [本地分支],那就等因而在說「在這裏提取空白而後把它變成[遠程分支]」。

在服務器上部署 Git

開始架設 Git 服務器前,須要先把現有倉庫導出爲裸倉庫 — 即一個不包含當前工做目錄的倉庫。克隆時用 --bare 選項便可。裸倉庫的目錄名通常以.git 結尾,像這樣:

$ git clone --bare my_project my_project.git
Initialized empty Git repository in /opt/projects/my_project.git/

有了裸倉庫的副本後,剩下的就是把它放到服務器上並設定相關協議。假設一個域名爲 git.example.com 的服務器已經架設好,並能夠經過 SSH 訪問,咱們打算把全部 Git 倉庫儲存在/opt/git 目錄下。只要把裸倉庫複製過去:

$ scp -r my_project.git user@git.example.com:/opt/git

如今,全部對該服務器有 SSH 訪問權限,並可讀取 /opt/git 目錄的用戶均可以用下面的命令克隆該項目:

$ git clone user@git.example.com:/opt/git/my_project.git

若是某個 SSH 用戶對 /opt/git/my_project.git 目錄有寫權限,那他就有推送權限。
因而可知,根據現有的 Git 倉庫建立一個裸倉庫,而後把它放上你和同事都有 SSH 訪問權的服務器是多麼容易。如今已經能夠開始在同一項目上密切合做了。
這是架設一個少數人具備鏈接權的 Git 服務的所有 — 只要在服務器上加入能夠用 SSH 登陸的賬號,而後把裸倉庫放在你們都有讀寫權限的地方。一切都準備停當,無需更多。

小型安裝

若是設備較少或者你只想在小型開發團隊裏嘗試 Git ,那麼一切都很簡單。架設 Git 服務最複雜的地方在於帳戶管理。若是須要倉庫對特定的用戶可讀,而給另外一部分用戶讀寫權限,那麼訪問和許可的安排就比較困難。
SSH 鏈接

若是已經有了一個全部開發成員均可以用 SSH 訪問的服務器,架設第一個服務器將變得異常簡單,幾乎什麼都不用作(正如上節中介紹的那樣)。若是須要對倉庫進行更復雜的訪問控制,只要使用服務器操做系統的本地文件訪問許可機制就好了。

若是須要團隊裏的每一個人都對倉庫有寫權限,又不能給每一個人在服務器上創建帳戶,那麼提供 SSH 鏈接就是惟一的選擇了。咱們假設用來共享倉庫的服務器已經安裝了 SSH 服務,並且你經過它訪問服務器。

有好幾個辦法可讓團隊的每一個人都有訪問權。
第一個辦法是給每一個人創建一個帳戶,直截了當但略過繁瑣。反覆運行 adduser 並給全部人設定臨時密碼可不是好玩的。

第二個辦法是在主機上創建一個 git 帳戶,讓每一個須要寫權限的人發送一個 SSH 公鑰,而後將其加入 git 帳戶的~/.ssh/authorized_keys 文件。這樣一來,全部人都將經過 git 帳戶訪問主機。這絲絕不會影響提交的數據 — 訪問主機用的身份不會影響提交對象的提交者信息。

另外一個辦法是讓 SSH 服務器經過某個 LDAP 服務,或者其餘已經設定好的集中受權機制,來進行受權。只要每一個人都能得到主機的 shell 訪問權,任何可用的 SSH 受權機制都能達到相同效果。

1. 生成 SSH 公鑰

大多數 Git 服務器都會選擇使用 SSH 公鑰來進行受權。系統中的每一個用戶都必須提供一個公鑰用於受權,沒有的話就要生成一個。生成公鑰的過程在全部操做系統上都差很少。首先先確認一下是否已經有一個公鑰了。SSH 公鑰默認儲存在帳戶的主目錄下的~/.ssh 目錄。進去看看:

$ cd ~/.ssh
$ ls
authorized_keys2  id_dsa       known_hosts
config            id_dsa.pub

關鍵是看有沒有用 something 和 something.pub 來命名的一對文件,這個 something 一般就是 id_dsa 或 id_rsa。有 .pub 後綴的文件就是公鑰,另外一個文件則是密鑰。假如沒有這些文件,或者乾脆連.ssh 目錄都沒有,能夠用 ssh-keygen 來建立。該程序在 Linux/Mac 系統上由 SSH 包提供,而在 Windows 上則包含在 MSysGit 包裏:

$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
The key fingerprint is:
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local

它先要求你確認保存公鑰的位置(.ssh/id_rsa),而後它會讓你重複一個密碼兩次,若是不想在使用公鑰的時候輸入密碼,能夠留空。

如今,全部作過這一步的用戶都得把它們的公鑰給你或者 Git 服務器的管理員(假設 SSH 服務被設定爲使用公鑰機制)。他們只須要複製 .pub 文件的內容而後發郵件給管理員。公鑰的樣子大體以下:

$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== schacon@agadorlaptop.local

關於在多個操做系統上設立相同 SSH 公鑰的教程,能夠查閱 GitHub 上有關 SSH 公鑰的嚮導:http://github.com/guides/prov...

2. 架設服務器

如今咱們過一邊服務器端架設 SSH 訪問的流程。本例將使用 authorized_keys 方法來給用戶受權。咱們還將假定使用相似 Ubuntu 這樣的標準 Linux 發行版。首先,建立一個名爲 ‘git’ 的用戶,併爲其建立一個.ssh 目錄。

$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh

接下來,把開發者的 SSH 公鑰添加到這個用戶的 authorized_keys 文件中。假設你經過電郵收到了幾個公鑰並存到了臨時文件裏。重複一下,公鑰大體看起來是這個樣子:

$ cat /tmp/id_rsa.john.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L
ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k
Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez
Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv
O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq
dAv8JggJICUvax2T9va5 gsg-keypair

只要把它們逐個追加到 authorized_keys 文件尾部便可:

$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys

如今能夠用 --bare 選項運行 git init 來創建一個裸倉庫,這會初始化一個不包含工做目錄的倉庫。

$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git --bare init

這時,Join,Josie 或者 Jessica 就能夠把它加爲遠程倉庫,推送一個分支,從而把第一個版本的項目文件上傳到倉庫裏了。值得注意的是,每次添加一個新項目都須要經過 shell 登入主機並建立一個裸倉庫目錄。咱們不妨以gitserver 做爲 git 用戶及項目倉庫所在的主機名。若是在網絡內部運行該主機,並在 DNS 中設定 gitserver 指向該主機,那麼如下這些命令都是可用的:

# 在 John 的電腦上
$ cd myproject
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@gitserver:/opt/git/project.git
$ git push origin master

這樣,其餘人的克隆和推送也同樣變得很簡單:

$ git clone git@gitserver:/opt/git/project.git
$ vim README
$ git commit -am 'fix for the README file'
$ git push origin master

用這個方法能夠很快捷地爲少數幾個開發者架設一個可讀寫的 Git 服務。

做爲一個額外的防範措施,你能夠用 Git 自帶的 git-shell 工具限制 git 用戶的活動範圍。只要把它設爲git 用戶登入的 shell,那麼該用戶就沒法使用普通的 bash 或者 csh 什麼的 shell 程序。編輯 /etc/passwd 文件:

$ sudo vim /etc/passwd

在文件末尾,你應該能找到相似這樣的行:

git:x:1000:1000::/home/git:/bin/sh

bin/sh 改成 /usr/bin/git-shell (或者用 which git-shell 查看它的實際安裝路徑)。該行修改後的樣子以下:

git:x:1000:1000::/home/git:/usr/bin/git-shell

如今 git 用戶只能用 SSH 鏈接來推送和獲取 Git 倉庫,而不能直接使用主機 shell。嘗試普通 SSH 登陸的話,會看到下面這樣的拒絕信息:

$ ssh git@gitserver
fatal: What do you think I am? A shell?
Connection to gitserver closed.

Gitosis 能夠設置誰能讀或者寫哪一個項目

把全部用戶的公鑰保存在 authorized_keys 文件的作法,只能湊和一陣子,當用戶數量達到幾百人的規模時,管理起來就會十分痛苦。每次改刪用戶都必須登陸服務器不去說,這種作法還缺乏必要的權限管理 — 每一個人都對全部項目擁有完整的讀寫權限。

幸虧咱們還能夠選擇應用普遍的 Gitosis 項目。簡單地說,Gitosis 就是一套用來管理 authorized_keys 文件和實現簡單鏈接限制的腳本。有趣的是,用來添加用戶和設定權限的並不是經過網頁程序,而只是管理一個特殊的 Git 倉庫。你只須要在這個特殊倉庫內作好相應的設定,而後推送到服務器上,Gitosis 就會隨之改變運行策略,聽起來就很酷,對吧?

Gitosis 的安裝算不上傻瓜化,但也不算太難。用 Linux 服務器架設起來最簡單 — 如下例子中,咱們使用裝有 Ubuntu 8.10 系統的服務器。

Gitosis 的工做依賴於某些 Python 工具,因此首先要安裝 Python 的 setuptools 包,在 Ubuntu 上稱爲 python-setuptools:

$ apt-get install python-setuptools

接下來,從 Gitosis 項目主頁克隆並安裝:

$ git clone git://eagain.net/gitosis.git
$ cd gitosis
$ sudo python setup.py install

這會安裝幾個供 Gitosis 使用的工具。默認 Gitosis 會把 /home/git 做爲存儲全部 Git 倉庫的根目錄,這沒什麼很差,不過咱們以前已經把項目倉庫都放在/opt/git 裏面了,因此爲方便起見,咱們能夠作一個符號鏈接,直接劃轉過去,而沒必要從新配置:

$ ln -s /opt/git /home/git/repositories

Gitosis 將會幫咱們管理用戶公鑰,因此先把當前控制文件更名備份,以便稍後從新添加,準備好讓 Gitosis 自動管理 authorized_keys 文件:

$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak

接下來,若是以前把 git 用戶的登陸 shell 改成 git-shell 命令的話,先恢復 ‘git’ 用戶的登陸 shell。改過以後,你們仍然沒法經過該賬號登陸(譯註:由於authorized_keys 文件已經沒有了。),不過不用擔憂,這會交給 Gitosis 來實現。因此如今先打開 /etc/passwd 文件,把這行:

git:x:1000:1000::/home/git:/usr/bin/git-shell

改回:

git:x:1000:1000::/home/git:/bin/sh

好了,如今能夠初始化 Gitosis 了。你能夠用本身的公鑰執行 gitosis-init 命令,要是公鑰不在服務器上,先臨時複製一份:

$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
Initialized empty Git repository in /opt/git/gitosis-admin.git/
Reinitialized existing Git repository in /opt/git/gitosis-admin.git/

這樣該公鑰的擁有者就能修改用於配置 Gitosis 的那個特殊 Git 倉庫了。接下來,須要手工對該倉庫中的 post-update 腳本加上可執行權限:

$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update

基本上就算是好了。若是設定過程沒出什麼差錯,如今能夠試一下用初始化 Gitosis 的公鑰的擁有者身份 SSH 登陸服務器,應該會看到相似下面這樣:

$ ssh git@gitserver
PTY allocation request failed on channel 0
fatal: unrecognized command 'gitosis-serve schacon@quaternion'
  Connection to gitserver closed.

說明 Gitosis 認出了該用戶的身份,但因爲沒有運行任何 Git 命令,因此它切斷了鏈接。那麼,如今運行一個實際的 Git 命令 — 克隆 Gitosis 的控制倉庫:

# 在你本地計算機上
$ git clone git@gitserver:gitosis-admin.git

這會獲得一個名爲 gitosis-admin 的工做目錄,主要由兩部分組成:

$ cd gitosis-admin
$ find .
./gitosis.conf
./keydir
./keydir/scott.pub

gitosis.conf 文件是用來設置用戶、倉庫和權限的控制文件。keydir 目錄則是保存全部具備訪問權限用戶公鑰的地方— 每人一個。在keydir 裏的文件名(好比上面的 scott.pub)應該跟你的不同 — Gitosis 會自動從使用 gitosis-init 腳本導入的公鑰尾部的描述中獲取該名字。

看一下 gitosis.conf 文件的內容,它應該只包含與剛剛克隆的 gitosis-admin 相關的信息:

$ cat gitosis.conf 
[gitosis]

[group gitosis-admin]
writable = gitosis-admin
members = scott

它顯示用戶 scott — 初始化 Gitosis 公鑰的擁有者 — 是惟一能管理 gitosis-admin 項目的人。

如今咱們來添加一個新項目。爲此咱們要創建一個名爲 mobile 的新段落,在其中羅列手機開發團隊的開發者,以及他們擁有寫權限的項目。因爲 ‘scott’ 是系統中的惟一用戶,咱們把他設爲惟一用戶,並容許他讀寫名爲iphone_project 的新項目:

[group mobile]
writable = iphone_project
members = scott

修改完以後,提交 gitosis-admin 裏的改動,並推送到服務器使其生效:

$ git commit -am 'add iphone_project and mobile group'
[master]: created 8962da8: "changed name"
 1 files changed, 4 insertions(+), 0 deletions(-)
$ git push
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 272 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@gitserver:/opt/git/gitosis-admin.git
   fb27aec..8962da8  master -> master

在新工程 iphone_project 裏首次推送數據到服務器前,得先設定該服務器地址爲遠程倉庫。但你不用事先到服務器上手工建立該項目的裸倉庫— Gitosis 會在第一次遇到推送時自動建立:

$ git remote add origin git@gitserver:iphone_project.git
$ git push origin master
Initialized empty Git repository in /opt/git/iphone_project.git/
Counting objects: 3, done.
Writing objects: 100% (3/3), 230 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitserver:iphone_project.git
 * [new branch]      master -> master

請注意,這裏不用指明完整路徑(實際上,若是加上反而沒用),只須要一個冒號加項目名字便可 — Gitosis 會自動幫你映射到實際位置。

要和朋友們在一個項目上協同工做,就得從新添加他們的公鑰。不過此次不用在服務器上一個一個手工添加到 ~/.ssh/authorized_keys 文件末端,而只需管理keydir 目錄中的公鑰文件。文件的命名將決定在 gitosis.conf 中對用戶的標識。如今咱們爲 John,Josie 和 Jessica 添加公鑰:

$ cp /tmp/id_rsa.john.pub keydir/john.pub
$ cp /tmp/id_rsa.josie.pub keydir/josie.pub
$ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub

而後把他們都加進 ‘mobile’ 團隊,讓他們對 iphone_project 具備讀寫權限:

[group mobile]
writable = iphone_project
members = scott john josie jessica

若是你提交併推送這個修改,四個用戶將同時具備該項目的讀寫權限。

Gitosis 也具備簡單的訪問控制功能。若是想讓 John 只有讀權限,能夠這樣作:

[group mobile]
writable = iphone_project
members = scott josie jessica

[group mobile_ro]
readonly = iphone_project
members = john

如今 John 能夠克隆和獲取更新,但 Gitosis 不會容許他向項目推送任何內容。像這樣的組能夠隨意建立,多少不限,每一個均可以包含若干不一樣的用戶和項目。甚至還能夠指定某個組爲成員之一(在組名前加上@ 前綴),自動繼承該組的成員:

[group mobile_committers]
members = scott josie jessica

[group mobile]
writable  = iphone_project
members   = @mobile_committers

[group mobile_2]
writable  = another_iphone_project
members   = @mobile_committers john

若是遇到意外問題,試試看把 loglevel=DEBUG 加到 [gitosis] 的段落(譯註:把日誌設置爲調試級別,記錄更詳細的運行信息。)。若是一不當心搞錯了配置,失去了推送權限,也能夠手工修改服務器上的/home/git/.gitosis.conf 文件 — Gitosis 實際是從該文件讀取信息的。它在獲得推送數據時,會把新的 gitosis.conf 存到該路徑上。因此若是你手工編輯該文件的話,它會一直保持到下次向 gitosis-admin 推送新版本的配置內容爲止。

工做流程

提交規範

請將每次提交限定於完成一次邏輯功能。而且可能的話,適當地分解爲屢次小更新,以便每次小型提交都更易於理解。請不要在週末窮追猛打一次性 解決五個問題,而最後拖到週一再提交。就算是這樣也請儘量利用暫存區域,將以前的改動分解爲每次修復一個問題,再分別提交和加註說明。若是針對兩個問題 改動的是同一個文件,能夠試試看git add --patch 的方式將部份內容置入暫存區域(咱們會在第六章再詳細介紹)。不管是五次小提交仍是混雜在一塊兒的大提交,最終分支末端的項目快照應該仍是同樣的,但分解開 來以後,更便於其餘開發者複閱。這麼作也方便本身未來取消某個特定問題的修復。咱們將在第六章介紹一些重寫提交歷史,同暫存區域交互的技巧和工具,以便最 終獲得一個乾淨有意義,且易於理解的提交歷史

最後須要謹記的是提交說明的撰寫。寫得好可讓你們協做起來更輕鬆。通常來講,提交說明最好限制在一行之內,50 個字符如下,簡明扼要地描述更新內容,空開一行後,再展開詳細註解。Git 項目自己須要開發者撰寫詳盡註解,包括本次修訂的因由,以及先後不一樣實現之間的比較,咱們也該借鑑這種作法

例如

本次更新的簡要描述(50 個字符之內)

若是必要,此處展開詳盡闡述。段落寬度限定在 72 個字符之內。
某些狀況下,第一行的簡要描述將用做郵件標題,其他部分做爲郵件正文。
其間的空行是必要的,以區分二者(固然沒有正文另當別論)。
若是並在一塊兒,rebase 這樣的工具就可能會迷惑。

另起空行後,再進一步補充其餘說明。

 - 可使用這樣的條目列舉式。

 - 通常以單個空格緊跟短劃線或者星號做爲每項條目的起始符。每一個條目間用一空行隔開。
   不過這裏按本身項目的約定,能夠略做變化。
  • 工做流程

    最簡單的協做方式之一:先在本身的特性分支中工做一段時間,完成後合併到本身的 master 分支;而後下載合併 origin/master 上的更新(若是有的話),再推回遠程服務器。
相關文章
相關標籤/搜索