1. 程式人生 > >Git 常用技巧

Git 常用技巧

## Git 簡介

Git 是一種程式碼管理方式,用於多人協作開發。Git 有如下特點:

- 分佈儲存在多臺電腦上

- 任意兩個開發者之間可以很容易的解決衝突。

- 離線工作

Pro Git(中文版)  返回 碼雲

目錄

  1. 1.起步

    1. 1.1 關於版本控制
    2. 1.2 Git 簡史
    3. 1.3 Git 基礎
    4. 1.4 安裝 Git
    5. 1.5 初次執行 Git 前的配置
    6. 1.6 獲取幫助
    7. 1.7 小結
  2. 2.Git 基礎

    1. 2.1 取得專案的 Git 倉庫
    2. 2.2 記錄每次更新到倉庫
    3. 2.3 檢視提交歷史
    4. 2.4 撤消操作
    5. 2.5 遠端倉庫的使用
    6. 2.6 打標籤
    7. 2.7 技巧和竅門
    8. 2.8 小結
  3. 3.Git 分支

    1. 3.1 何謂分支
    2. 3.2 分支的新建與合併
    3. 3.3 分支的管理
    4. 3.4 利用分支進行開發的工作流程
    5. 3.5 遠端分支
    6. 3.6 分支的衍合
    7. 3.7 小結
  4. 4.伺服器上的 Git

    1. 4.1 協議
    2. 4.2 在伺服器上部署 Git
    3. 4.3 生成 SSH 公鑰
    4. 4.4 架設伺服器
    5. 4.5 公共訪問
    6. 4.6 GitWeb
    7. 4.7 Gitosis
    8. 4.8 Gitolite
    9. 4.9 Git 守護程序
    10. 4.10 Git 託管服務
    11. 4.11 小結
  5. 5.分散式 Git

    1. 5.1 分散式工作流程
    2. 5.2 為專案作貢獻
    3. 5.3 專案的管理
    4. 5.4 小結
  6. 6.Git 工具

    1. 6.1 修訂版本(Revision)選擇
    2. 6.2 互動式暫存
    3. 6.3 儲藏(Stashing)
    4. 6.4 重寫歷史
    5. 6.5 使用 Git 除錯
    6. 6.6 子模組
    7. 6.7 子樹合併
    8. 6.8 總結
  7. 7.自定義 Git

    1. 7.1 配置 Git
    2. 7.2 Git屬性
    3. 7.3 Git掛鉤
    4. 7.4 Git 強制策略例項
    5. 7.5 總結
  8. 8.Git 與其他系統

    1. 8.1 Git 與 Subversion
    2. 8.2 遷移到 Git
    3. 8.3 總結
  9. 9.Git 內部原理

    1. 9.1 底層命令 (Plumbing) 和高層命令 (Porcelain)
    2. 9.2 Git 物件
    3. 9.3 Git References
    4. 9.4 Packfiles
    5. 9.5 The Refspec
    6. 9.6 傳輸協議
    7. 9.7 維護及資料恢復
    8. 9.8 總結

返回碼雲 | Git 官方網站 | Git 手冊 | Pro Git 原始碼

http://git.oschina.net/progit/3-Git-%E5%88%86%E6%94%AF.html#3.4-%E5%88%A9%E7%94%A8%E5%88%86%E6%94%AF%E8%BF%9B%E8%A1%8C%E5%BC%80%E5%8F%91%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B

1.配置使用者資訊

$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]

2.檢視配置資訊

$ git config --list

3.獲取幫助

git help config

4.對現有的某個專案用git進行管理

git init

5.從現有的倉庫克隆

git clone [url]

6.檢視當前檔案狀態

git status

7.跟蹤新檔案

git add .  //跟蹤所有的新檔案,並處於暫存狀態

git add 1.txt //跟蹤某個新檔案,並處於暫存狀態

8.檢視具體修改了什麼地方

git diff //此命令只能檢視已修改但未暫存起來的變化內容

git diff --staged 或 git diff --cached //此命令只能檢視暫存起來的檔案的內容變化

9.提交更新

git commit 

git commit -m 'xxxx' //加-m引數後此命令可跟提交說明方式

git commit -a -m 'xxxx' //加 -a引數後此命令會自動把已經跟蹤過的檔案暫存起來一併提交,跳過使用暫存區域(注意:新新增的檔案卻不能用此命令)

10.移除檔案

git rm --cached b.vue //從暫存區中移除某個檔案,但工作目錄中仍然存在

git rm -f b.vue //強制刪除某個檔案,工作目錄中也刪除掉

11.檢視提交歷史

git log //不帶任何的引數,按提交時間列出所有的更新,最近的排在最上面

git  log -p //選項展開顯示每次提交的內容差異

git log -2 //僅展示最近的兩次更新

git log --pretty=oneline //將每個提交放在一行顯示,這在提交數很大時非常有用

12.撤銷操作

(1)修改最後一次提交

有時候我們提交完了才發現漏掉了幾個檔案沒有加,或者提交資訊寫錯了。想要撤消剛才的提交操作,可以使用 --amend 選項重新提交:

git commit --amend

此命令將使用當前的暫存區域快照提交。如果剛才提交完沒有作任何改動,直接執行此命令的話,相當於有機會重新編輯提交說明,但將要提交的檔案快照和之前的一樣。

啟動文字編輯器後,會看到上次提交時的說明,編輯它確認沒問題後儲存退出,就會使用新的提交說明覆蓋剛才失誤的提交。

如果剛才提交時忘了暫存某些修改,可以先補上暫存操作,然後再執行 --amend 提交:

git commit -m 'lg'

git add .

git commit --amend

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

(2)取消已經暫存的檔案

接下來的兩個小節將演示如何取消暫存區域中的檔案,以及如何取消工作目錄中已修改的檔案。不用擔心,檢視檔案狀態的時候就提示了該如何撤消,所以不需要死記硬背。來看下面的例子,有兩個修改過的檔案,我們想要分開提交,但不小心用 git add . 全加到了暫存區域。該如何撤消暫存其中的一個檔案呢?其實,git status 的命令輸出已經告訴了我們該怎麼做:

$ git add .

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

就在 “Changes to be committed” 下面,括號中有提示,可以使用 git reset HEAD <file>... 的方式取消暫存。好吧,我們來試試取消暫存 benchmarks.rb 檔案:

$ git reset HEAD benchmarks.rb
    benchmarks.rb: locally modified
    $ git status
    # On branch master
    # Changes to be committed:
   
# (use "git reset HEAD <file>..." to unstage)
    #
    # modified: README.txt
    #
    # Changes not staged for commit:
    # (use "git add <file>..." to update what will be committed)
    # (use "git checkout -- <file>..." to discard changes in working directory)
    #
    # modified: benchmarks.rb

這條命令看起來有些古怪,先別管,能用就行。現在 benchmarks.rb 檔案又回到了之前已修改未暫存的狀態。

13.遠端倉庫的使用

要參與任何一個 Git 專案的協作,必須要了解該如何管理遠端倉庫。遠端倉庫是指託管在網路上的專案倉庫,可能會有好多個,其中有些你只能讀,另外有些可以寫。同他人協作開發某個專案時,需要管理這些遠端倉庫,以便推送或拉取資料,分享各自的工作進展。管理遠端倉庫的工作,包括新增遠端庫,移除廢棄的遠端庫,管理各式遠端庫分支,定義是否跟蹤這些分支,等等。本節我們將詳細討論遠端庫的管理和使用。

(1)檢視當前的遠端庫

要檢視當前配置有哪些遠端倉庫,可以用 git remote 命令,它會列出每個遠端庫的簡短名字。在克隆完某個專案後,至少可以看到一個名為 origin 的遠端庫,Git 預設使用這個名字來標識你所克隆的原始倉庫:

$ git clone git://github.com/schacon/ticgit.git
    Initialized empty Git repository in /private/tmp/ticgit/.git/
    remote: Counting objects: 595, done.
    remote: Compressing objects: 100% (269/269), done.
    remote: Total 595 (delta 255), reused 589 (delta 253)
    Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done.
    Resolving deltas: 100% (255/255), done.
    $ cd ticgit
    $ git remote
    origin

也可以加上 -v 選項(譯註:此為 --verbose 的簡寫,取首字母),顯示對應的克隆地址:

$ git remote -v
    origin git://github.com/schacon/ticgit.git

如果有多個遠端倉庫,此命令將全部列出。比如在我的 Grit 專案中,可以看到:

$ cd grit
    $ git remote -v
    bakkdoor git://github.com/bakkdoor/grit.git
    cho45 git://github.com/cho45/grit.git
    defunkt git://github.com/defunkt/grit.git
    koke git://github.com/koke/grit.git
    origin [email protected]:mojombo/grit.git

這樣一來,我就可以非常輕鬆地從這些使用者的倉庫中,拉取他們的提交到本地。請注意,上面列出的地址只有 origin 用的是 SSH URL 連結,所以也只有這個倉庫我能推送資料上去(我們會在第四章解釋原因)。

(2)新增遠端倉庫

要新增一個新的遠端倉庫,可以指定一個簡單的名字,以便將來引用,執行 git remote add [shortname] [url]

$ git remote
    origin
    $ git remote add pb git://github.com/paulboone/ticgit.git
    $ git remote -v
    origin git://github.com/schacon/ticgit.git
    pb git://github.com/paulboone/ticgit.git

現在可以用字串 pb 指代對應的倉庫地址了。比如說,要抓取所有 Paul 有的,但本地倉庫沒有的資訊,可以執行 git fetch pb

$ git fetch pb
    remote: Counting objects: 58, done.
    remote: Compressing objects: 100% (41/41), done.
    remote: Total 44 (delta 24), reused 1 (delta 0)
    Unpacking objects: 100% (44/44), done.
    From git://github.com/paulboone/ticgit
    * [new branch] master -> pb/master
    * [new branch] ticgit -> pb/ticgit

現在,Paul 的主幹分支(master)已經完全可以在本地訪問了,對應的名字是 pb/master,你可以將它合併到自己的某個分支,或者切換到這個分支,看看有些什麼有趣的更新。

(3)從遠端倉庫抓取資料

正如之前所看到的,可以用下面的命令從遠端倉庫抓取資料到本地:

$ git fetch [remote-name]

此命令會到遠端倉庫中拉取所有你本地倉庫中還沒有的資料。執行完成後,你就可以在本地訪問該遠端倉庫中的所有分支,將其中某個分支合併到本地,或者只是取出某個分支,一探究竟。(我們會在第三章詳細討論關於分支的概念和操作。)

如果是克隆了一個倉庫,此命令會自動將遠端倉庫歸於 origin 名下。所以,git fetch origin 會抓取從你上次克隆以來別人上傳到此遠端倉庫中的所有更新(或是上次 fetch 以來別人提交的更新)。有一點很重要,需要記住,fetch 命令只是將遠端的資料拉到本地倉庫,並不自動合併到當前工作分支,只有當你確實準備好了,才能手工合併。

如果設定了某個分支用於跟蹤某個遠端倉庫的分支(參見下節及第三章的內容),可以使用 git pull 命令自動抓取資料下來,然後將遠端分支自動合併到本地倉庫中當前分支。在日常工作中我們經常這麼用,既快且好。實際上,預設情況下 git clone 命令本質上就是自動建立了本地的 master 分支用於跟蹤遠端倉庫中的 master 分支(假設遠端倉庫確實有 master 分支)。所以一般我們執行 git pull,目的都是要從原始克隆的遠端倉庫中抓取資料後,合併到工作目錄中的當前分支。

(4)推送資料到遠端倉庫

專案進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的資料推送到遠端倉庫。實現這個任務的命令很簡單: git push [remote-name] [branch-name]。如果要把本地的 master 分支推送到 origin 伺服器上(再次說明下,克隆操作會自動使用預設的 master 和 origin 名字),可以執行下面的命令:

$ git push origin master

只有在所克隆的伺服器上有寫許可權,或者同一時刻沒有其他人在推資料,這條命令才會如期完成任務。如果在你推資料前,已經有其他人推送了若干更新,那你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,合併到自己的專案中,然後才可以再次推送。有關推送資料到遠端倉庫的詳細內容見第三章。

(5)檢視遠端倉庫資訊

我們可以通過命令 git remote show [remote-name] 檢視某個遠端倉庫的詳細資訊,比如要看所克隆的 origin 倉庫,可以執行:

$ git remote show origin
    * remote origin
    URL: git://github.com/schacon/ticgit.git
    Remote branch merged with 'git pull' while on branch master
    master
    Tracked remote branches
    master
    ticgit

除了對應的克隆地址外,它還給出了許多額外的資訊。它友善地告訴你如果是在 master 分支,就可以用 git pull 命令抓取資料合併到本地。另外還列出了所有處於跟蹤狀態中的遠端分支。

上面的例子非常簡單,而隨著使用 Git 的深入,git remote show 給出的資訊可能會像這樣:

$ git remote show origin
    * remote origin
    URL: [email protected]: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 分支)。

(6)遠端倉庫的刪除和重新命名

在新版 Git 中可以用 git remote rename 命令修改某個遠端倉庫在本地的簡稱,比如想把 pb 改成 paul,可以這麼執行:

$ git remote rename pb paul
    $ git remote
    origin
    paul

注意,對遠端倉庫的重新命名,也會使對應的分支名稱發生變化,原來的 pb/master 分支現在成了 paul/master

碰到遠端倉庫伺服器遷移,或者原來的克隆映象不再使用,又或者某個參與者不再貢獻程式碼,那麼需要移除對應的遠端倉庫,可以執行 git remote rm 命令:

$ git remote rm paul
    $ git remote
    origin

 

(7)有關分支

git branch #列出所有本地分支

git branch -r #列出所有遠端分支

git branch -a #列出所有分支(包括本地和遠端)

git branch [分支名]  #新增一個本地分支,但不切換

git checkout [分支名] #切換到該分支上

git checkout -b [分支名] #新建一個分支,並切換到這個分支上,相當於執行 git branch [分支名] 和 git checkout [分支名] 這兩步

git push origin [本地分支]:[遠端分支] #新建一個遠端分支,並把本地分支上的程式碼推送到新建的遠端分支上

git branch -d  [分支名]   #刪除本地分支

git push origin -d  [分支名]  #刪除遠端分支

git merge [某分支名]  #把某分支上的程式碼合併到當前分支上

(8)版本回退

在git中,用'HEAD'表示當前版本,也就是最新提交的版本;

上一個版本就是'HEAD^',上上一個版本就是'HEAD^^'

git reset --hard HEAD^   #從當前版本回退到上一個版本

git reset --hard HEAD^^  #從當前版本回退到上上一個版本

git reset --hard [版本號的前幾位]  #從當前版本回退到指定版本,例如:git reset --hard  1094a (沒必要寫全前幾位就可以);

在Git中,總是有後悔藥可以吃的。當你用$ git reset --hard HEAD^回退到add distributed(上一次版本)版本時,再想恢復到append GPL(最近的一次版本),就必須找到append GPL的commit id。Git提供了一個命令git reflog用來記錄你的每一次命令:

liujianguodeMacBook-Pro:gitweb liujianguo$ git reflog
b1ac482 (HEAD -> master) [email protected]{0}: reset: moving to b1ac4825
f1c173c [email protected]{1}: reset: moving to HEAD^
b1ac482 (HEAD -> master) [email protected]{2}: reset: moving to HEAD
b1ac482 (HEAD -> master) [email protected]{3}: commit: lg
f1c173c [email protected]{4}: commit: lg
df801e9 [email protected]{5}: commit (initial): lg

(8)撤銷修改

命令git checkout -- readme.txt意思就是,把readme.txt檔案在工作區的修改全部撤銷,這裡有兩種情況:

一種是readme.txt自修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;

一種是readme.txt已經新增到暫存區後,又作了修改,現在,撤銷修改就回到新增到暫存區後的狀態。

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

git checkout -- file命令中的--很重要,沒有--,就變成了“切換到另一個分支”的命令