Git基本使用總結

記錄一些Git的工作原理和最基本的使用


文件的三種狀態

在 Git 內部中,任何一個文件可分爲三種狀態:已提交(committed),已修改(modified)和已暫存(staged)。已提交表示該文件已經被安全地保存在本地數據庫中了;已修改表示修改了某個文件,但還沒有提交保存;已暫存表示把已修改的文件放在下次提交時要保存的清單中。
因此,Git 管理項目時,文件流轉在三個工作區域:Git 的工作目錄,暫存區域,本地倉庫。

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

基本的 Git 工作流程如下:

  • 在工作目錄中修改某些文件。
  • 對修改後的文件進行快照,然後保存到暫存區域。
  • 提交更新,將保存在暫存區域的文件快照永久轉儲到 Git 目錄中。

取得項目的 Git 倉庫

有兩種取得 Git 項目倉庫的方法。第一種是在現存的目錄下,通過導入所有文件來創建新的 Git 倉庫。第二種是從已有的 Git 倉庫克隆出一個新的鏡像倉庫來。

在工作目錄中初始化新倉庫

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

$ git init

初始化後,在當前目錄下會出現一個名爲 .git 的目錄,所有 Git 需要的數據和資源都存放在這個目錄中。
不過此時,我們只是在該目錄下初始化好了Git的相關結構,但是此時Git還沒有開始跟蹤管理項目中的任何一個文件

如果當前目錄下有幾個文件想要納入版本控制,需要先用 git add 命令告訴 Git 開始對這些文件進行跟蹤,然後提交:

$ git add *.c         //將所有的.c後綴文件加入跟蹤
    $ git add README     
    $ git commit -m 'initial project version'

從現有倉庫克隆

如果想克隆別人已有的倉庫,可以使用git clone 命令。
克隆倉庫的命令格式爲 git clone [url]
例如:$ git clone git://github.com/schacon/grit.git
這會在當前目錄下創建一個名爲grit的目錄,其中包含一個 .git 的目錄,用於保存下載下來的所有版本記錄,然後從中取出最新版本的文件拷貝。

如果希望在克隆的時候,自己定義要新建的項目目錄名稱,可以在上面的命令末尾指定新的名字:

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

Git 支持許多數據傳輸協議。
git協議:git:// ,http協議:http(s):// ,ssh協議:user@server:/path.git

記錄每次更新到倉庫

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

檢查當前文件狀態

可以用 git status 命令確定哪些文件當前處於什麼狀態。
如果在克隆倉庫之後立即執行此命令,會看到類似這樣的輸出:

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

這說明所有已跟蹤文件在上次提交後都未被更改過。
創建一個新文件 README,保存退出後運行git status會看到該文件出現在未跟蹤文件列表中:

$ vim README
    $ git status
    # On branch master
    # Untracked files:
    # (use "git add <file>..." to include in what will be committed)
    #
    # README
    nothing added to commit but untracked files present (use "git add" to track)

在狀態報告中可以看到新建的README文件出現在“Untracked files”下面,這說明此時README並未被Git跟蹤。

跟蹤新文件

使用命令 git add 開始跟蹤一個新文件。

$ git add README

此時再運行 git status 命令,會看到 README 文件已被跟蹤,並處於暫存狀態:

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

git add 後面可以指明要跟蹤的文件或目錄路徑。如果是目錄的話,就說明要遞歸跟蹤該目錄下的所有文件。

暫存已修改文件

現在我們修改下之前已跟蹤過的文件benchmarks.rb,然後再次運行 status 命令:

$ git status
    # On branch master
    # Changes to be committed:
    # (use "git reset HEAD <file>..." to unstage)
    #
    # new file: README
    #
    # Changes not staged for commit:
    # (use "git add <file>..." to update what will be committed)
    #
    # modified: benchmarks.rb
    #

文件 benchmarks.rb 出現在 “Changes not staged for commit” 這行下面,說明已跟蹤文件的內容發生了變化,但還沒有放到暫存區。要暫存這次更新,需要運行 git add 命令。
git add是個多功能命令,根據目標文件的狀態不同,此命令的效果也不同:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區,還能用於合併時把有衝突的文件標記爲已解決狀態等。

git status 的輸出:

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

現在兩個文件都已暫存,下次提交時就會一併記錄到倉庫。假設此時,在 benchmarks.rb 裏再加條註釋,重新編輯存盤後,準備好提交。此時運行git status,會看到這樣的情況:

$ vim benchmarks.rb
    $ git status
    # On branch master
    # Changes to be committed:
    # (use "git reset HEAD <file>..." to unstage)
    #
    # new file: README
    # modified: benchmarks.rb
    #
    # Changes not staged for commit:
    # (use "git add <file>..." to update what will be committed)
    #
    # modified: benchmarks.rb
    #

benchmarks.rb 文件出現了兩次,一次算未暫存,一次算已暫存。Git 只不過暫存了你運行 git add 命令時的版本,如果現在提交,那麼提交的是添加註釋前的版本,而非當前工作目錄中的版本。所以,運行了 git add 之後又作了修訂的文件,需要重新運行 git add 把最新版本重新暫存起來。

忽略某些文件

一般我們總會有些文件無需納入 Git 的管理,也不希望它們總出現在未跟蹤文件列表。通常都是些自動生成的文件,比如日誌文件,或者編譯過程中創建的臨時文件等。我們可以創建一個名爲 .gitignore 的文件,列出要忽略的文件模式。
例如:

$ cat .gitignore
    *.[oa]
    *~

第一行告訴 Git 忽略所有以 .o.a 結尾的文件。第二行告訴 Git 忽略所有以波浪符(~)結尾的文件。

查看已暫存和未暫存的更新

如果要查看具體修改了什麼地方,可以用 git diff 命令。
要查看尚未暫存的文件更新了哪些部分,不加參數直接輸入 git diff

$ git diff
    diff --git a/benchmarks.rb b/benchmarks.rb
    index 3cb747f..da65585 100644
    --- a/benchmarks.rb
    +++ b/benchmarks.rb
    @@ -36,6 +36,10 @@ def main
    @commit.parents[0].parents[0].parents[0]
    end

    + run_code(x, 'commits 1') do
    + git.commits.size
    + end
    +
    run_code(x, 'commits 2') do
    log = git.commits('master', 15)
    log.size

此命令比較的是工作目錄中當前文件和暫存區域快照之間的差異,也就是修改之後還沒有暫存起來的變化內容。

若要看已經暫存起來的文件和上次提交時的快照之間的差異,可以用 git diff --staged 命令。

$ git diff --cached
    diff --git a/README b/README
    new file mode 100644
    index 0000000..03902a1
    --- /dev/null
    +++ b/README2
    @@ -0,0 +1,5 @@
    +grit
    + by Tom Preston-Werner, Chris Wanstrath
    + http://github.com/mojombo/grit
    +
    +Grit is a Ruby library for extracting information from a Git repository

提交更新

使用git commit命令,將暫存區域的文件提交到git倉庫中。
這種方式會啓動文本編輯器以便輸入本次提交的說明。
通常我們在後面加上 -m參數,參數後直接跟這次提交的註解,可以直接在一行命令中提交。
例如:

$ git commit -m "Story 182: Fix benchmarks for speed"
    [master]: created 463dc4f: "Fix benchmarks for speed"
    2 files changed, 3 insertions(+), 0 deletions(-)
    create mode 100644 README

跳過使用暫存區域

每次提交前,我們都要先使用git add將修改後的文件,放入暫存區,纔可以使用git commit命令提交。
如果想省事,我們可以直接跳過使用暫存區域,直接提交更新後的文件。
Git 提供了一個跳過使用暫存區域的方式,只要在提交的時候,給 git commit 加上 -a 選項,Git 就會自動把所有已經跟蹤過的文件暫存起來一併提交,從而跳過 git add 步驟。

移除文件

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

另外一種情況是,我們想把文件從 Git 倉庫中刪除(亦即從暫存區域移除),但仍然希望保留在當前工作目錄中。換句話說,僅是從跟蹤清單中刪除。用 --cached 選項即可:

$ git rm --cached readme.txt

重命名文件

要在 Git 中對文件改名,可以使用 git mv命令。
例如:$ git mv file_from file_to
其實,運行 git mv 就相當於運行了下面三條命令:

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

查看提交歷史

可以使用 git log 命令查看提交歷史。
默認不用任何參數的話,git log 會按提交時間列出所有的更新,最近的更新排在最上面。每次更新都有一個 SHA-1 校驗和、作者的名字和電子郵件地址、提交時間,最後縮進一個段落顯示提交說明。
我們常用 -p 選項展開顯示每次提交的內容差異,用 -2 則僅顯示最近的兩次更新:

$ git log -p -2

撤消操作

修改最後一次提交

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

   $ git commit --amend

此命令將使用當前的暫存區域快照提交。如果剛纔提交完沒有作任何改動,直接運行此命令的話,相當於有機會重新編輯提交說明,但將要提交的文件快照和之前的一樣。
啓動文本編輯器後,會看到上次提交時的說明,編輯它確認沒問題後保存退出,就會使用新的提交說明覆蓋剛纔失誤的提交。
如果剛纔提交時忘了暫存某些修改,可以先補上暫存操作,然後再運行 --amend 提交:

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

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

取消已經暫存的文件

下面的例子,有兩個修改過的文件,我們想要分開提交,但不小心用 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 的修改完全沒有必要,該如何取消修改,回到之前的狀態(也就是修改之前的版本)呢?git status 同樣提示了具體的撤消方法:

# 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
    #

即,使用命令:

git checkout -- <file>...

遠程倉庫的使用

遠程倉庫是指託管在網絡上的項目倉庫,可能會有好多個,其中有些你只能讀,另外有些可以寫。同他人協作開發某個項目時,需要管理這些遠程倉庫,以便推送或拉取數據,分享各自的工作進展。

查看當前的遠程庫

要查看當前配置有哪些遠程倉庫,可以用 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 選項,顯示對應的克隆地址:

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

添加遠程倉庫

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

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

從遠程倉庫抓取數據

如果設置了某個分支用於跟蹤某個遠端倉庫的分支,可以使用 git pull 命令自動抓取數據下來,然後將遠端分支自動合併到本地倉庫中當前分支。

推送數據到遠程倉庫

項目進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的數據推送到遠程倉庫:

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

如果要把本地的 master 分支推送到 origin 服務器上(再次說明下,克隆操作會自動使用默認的 masterorigin 名字),可以運行下面的命令:

$ git push origin master

只有在所克隆的服務器上有寫權限,或者同一時刻沒有其他人在推數據,這條命令纔會如期完成任務。如果在你推數據前,已經有其他人推送了若干更新,那你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,合併到自己的項目中,然後纔可以再次推送。

查看遠程倉庫信息

我們可以通過命令 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

遠程倉庫的刪除和重命名

可以用 git remote rename 命令修改某個遠程倉庫在本地的簡稱,比如想把 pb 改成 paul:

$ git remote rename pb paul
    $ git remote
    origin
    paul

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

$ git remote rm paul
    $ git remote
    origin
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章