GIT 學習筆記(2) —— GIT 基礎

基本操作

git init : 初始化工作空間,產生.git目錄,用於存放數據及資源。

git add filename : 將file添加到被跟蹤文件中(即版本控制中);修改後的文件發佈新的版本也需要執行此命令添加到暫存區。

git clone projectUrl name :將存在的項目從其他地方複製過來,並取好別名name。

git status :查看項目中的文件狀態,只會顯示已在版本控制中的文件狀態(modified,added,deleted)。

-s 緊湊的格式輸出

git diff :能查看本地與暫存區及版本控制中的文件的不同之處,並用文件補丁的方式顯示具體增加或刪除的行。

–cached/staged 看已經暫存起來的變化

git commit : 將保存在暫存區中的文件(可能是最近幾次add但沒提交的)全部提交到一個新的版本。

-m msg msg爲提交版本的註釋

-a 將所有在版本控制中的文件全部提交,而不管是否是手動add過的

–amend 將新的文件與上一次提交的文件合併成一次提交

git reset HEAD file 取消放在在暫存區中要提交的文件

git cheakout -- file 不修改本次文件,從版本庫中取得最新的文件

git rm :刪除版本控制的文件,若在提交前有修改,則需要加-f強制刪除。

–cached 僅從暫存區刪除,當前目錄中還是存在該文件

git mv file1 file2:移動文件,重命名。

$ git cat-file -p HEAD 顯示 HEAD 快照內容

$ git ls-tree -r HEAD 顯示 HEAD 快照實際的目錄列表

$ git ls-files -s 顯示索引區(index)目錄

Git

日誌

git log :查看日誌。

-p:提交日誌的內容差異

-n:查看最近n次 的提交

-stat:顯示每次修改的行數

–pretty:(重要)

=oneline/short/full/fuller

=format,git log –pretty=format:”%h - %an,%ar:%s”

–since/after/befor

–auchor 指定作者

–grep 註釋中出現的詞

遠程倉庫

git remote :顯示遠程倉庫。

-v (verbose) 顯示對應的克隆地址

git remote add <shortname> <url> :增加新的遠程倉庫。

git fetch [remote-name]: 從倉庫中獲取最新版本的數據

git push [remote-name] [branch-name] :推送新的數據到遠程倉庫

git remote show [remote-name]:查看遠程倉庫的信息

git remote rename [remote-name-old] [remote-name-new] :修改倉庫別名(一般不會更改,多了你自己都搞不清楚了)。

git remote rm [remote-name]:刪除遠程倉庫。

標籤

git tag :將完整的一個版本加上標籤有助於區分。

-l 列表顯示所有標籤,可跟正則表達式篩選

-a 新增一個標籤

-m 標籤說明,一般與新增標籤一起使用

git show :顯示相應標籤的版本信息,並連同顯示打標籤時的提交對象。

git push origin [tagname] : 推送標籤到遠程倉庫服務器

git push origin --tags : 推送所有標籤到遠程倉庫服務器

git checkout -b [branchname] [tagname] : 在特定的標籤上創建一個新分支




Git 基礎

獲取 Git 倉庫

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

$ git init

2. 克隆現有的倉庫

git clone [url] name
// url 倉庫的地址
// name 別名

記錄更新

現在我們手上有了一個真實項目的 Git 倉庫,並從這個倉庫中取出了所有文件的工作拷貝。接下來,對這些文件做些修改,在完成了一個階段的目標之後,提交本次更新到倉庫。

請記住,你工作目錄下的每一個文件都不外乎這兩種狀態:已跟蹤或未跟蹤。已跟蹤的文件是指那些被納入了版本控制的文件,在上一次快照中有它們的記錄,在工作一段時間後,它們的狀態可能處於未修改,已修改或已放入暫存區。工作目錄中除已跟蹤文件以外的所有其它文件都屬於未跟蹤文件,它們既不存在於上次快照的記錄中,也沒有放入暫存區。初次克隆某個倉庫的時候,工作目錄中的所有文件都屬於已跟蹤文件,並處於未修改狀態。

編輯過某些文件之後,由於自上次提交後你對它們做了修改,Git 將它們標記爲已修改文件。我們逐步將這些修改過的文件放入暫存區,然後提交所有暫存了的修改,如此反覆。所以使用 Git 時文件的生命週期如下:

檢查當前文件狀態

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

$ git status
On branch master
nothing to commit, working directory clean

這說明你現在的工作目錄相當乾淨。換句話說,所有已跟蹤文件在上次提交後都未被更改過。此外,上面的信息還表明,當前目錄下沒有出現任何處於未跟蹤狀態的新文件,否則 Git 會在這裏列出來。最後,該命令還顯示了當前所在分支,並告訴你這個分支同遠程服務器上對應的分支沒有偏離。現在,分支名是 “master”,這是默認的分支名。

現在,我們在項目下創建一個新的 README 文件。如果之前並不存在這個文件,使用 git status 命令,你將看到一個新的未跟蹤文件:

$ echo 'My Project' > README
$ git status
On branch master
Untracked files:
(use “git add …” to include in what will be committed)

README

nothing added to commit but untracked files present (use “git add” to track)

在狀態報告中可以看到新建的 README 文件出現在 Untracked files 下面。未跟蹤的文件意味着 Git 在之前的快照(提交)中沒有這些文件;Git 不會自動將之納入跟蹤範圍,除非你明明白白地告訴它“我需要跟蹤該文件”,這樣的處理讓你不必擔心將生成的二進制文件或其它不想被跟蹤的文件包含進來。

跟蹤新文件

使用命令 git add 開始跟蹤一個文件。所以,要跟蹤 README 文件,運行:

$ git add README

狀態簡覽

git status 命令的輸出十分詳細,但其用語有些繁瑣。如果你使用 git status -s 命令或 git status --short 命令,你將得到一種更爲緊湊的格式輸出。運行 git status -s ,狀態報告輸出如下:

$ git status -s
   M README
MM Rakefile
A    lib/git.rb
M    lib/simplegit.rb
??   LICENSE.txt

新添加的未跟蹤文件前面有 ?? 標記,新添加到暫存區中的文件前面有 A 標記,修改過的文件前面有 M 標記。你可能注意到了 M 有兩個可以出現的位置,出現在右邊的 M 表示該文件被修改了但是還沒放入暫存區,出現在靠左邊的 M 表示該文件被修改了並放入了暫存區。例如,上面的狀態報告顯示: README 文件在工作區被修改了但是還沒有將修改後的文件放入暫存區,lib/simplegit.rb 文件被修改了並將修改後的文件放入了暫存區。而 Rakefile 在工作區被修改並提交到暫存區後又在工作區中被修改了,所以在暫存區和工作區都有該文件被修改了的記錄。

忽略文件

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

$ cat .gitignore
*.[oa]
*~

第一行告訴 Git 忽略所有以 .o 或 .a 結尾的文件。一般這類對象文件和存檔文件都是編譯過程中出現的。第二行告訴 Git 忽略所有以波浪符(~)結尾的文件,許多文本編輯軟件(比如 Emacs)都用這樣的文件名保存副本。此外,你可能還需要忽略 log,tmp 或者 pid 目錄,以及自動生成的文檔等等。要養成一開始就設置好 .gitignore 文件的習慣,以免將來誤提交這類無用的文件。

文件 .gitignore 的格式規範如下:

  • 所有空行或者以 # 開頭的行都會被 Git 忽略。
  • 可以使用標準的 glob 模式匹配。
  • 匹配模式可以以(/)開頭防止遞歸。
  • 匹配模式可以以(/)結尾指定目錄。
  • 要忽略指定模式以外的文件或目錄,可以在模式前加上驚歎號(!)取反。

所謂的 glob 模式是指 shell 所使用的簡化了的正則表達式。星號(*)匹配零個或多個任意字符;[abc] 匹配任何一個列在方括號中的字符(這個例子要麼匹配一個 a,要麼匹配一個 b,要麼匹配一個 c);問號(?)只匹配一個任意字符;如果在方括號中使用短劃線分隔兩個字符,表示所有在這兩個字符範圍內的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的數字)。使用兩個星號(*) 表示匹配任意中間目錄,比如a/**/z 可以匹配 a/z, a/b/z 或 a/b/c/z等。

# 此爲註釋 – 將被 Git 忽略
# 忽略所有 .a 結尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 僅僅忽略項目根目錄下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目錄下的所有文件
build/
# 會忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt

提交更新

在的暫存區域已經準備妥當可以提交了。在此之前,請一定要確認還有什麼修改過的或新建的文件還沒有 git add 過,否則提交的時候不會記錄這些還沒暫存起來的變化。這些修改過的文件只保留在本地磁盤。所以,每次準備提交前,先用 git status 看下,是不是都已暫存起來了,然後再運行提交命令 git commit:

$ git commit

這種方式會啓動文本編輯器以便輸入本次提交的說明。

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   new file:   README
#   modified:   CONTRIBUTING.md
#
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C

可以看到,默認的提交消息包含最後一次運行 git status 的輸出,放在註釋行裏,另外開頭還有一空行,供你輸入提交說明。你完全可以去掉這些註釋行,不過留着也沒關係,多少能幫你回想起這次更新的內容有哪些。(如果想要更詳細的對修改了哪些內容的提示,可以用 -v 選項,這會將你所做的改變的 diff 輸出放到編輯器中從而使你知道本次提交具體做了哪些修改。)退出編輯器時,Git 會丟掉註釋行,用你輸入提交附帶信息生成一次提交。

另外,你也可以在 commit 命令後添加 -m 選項,將提交信息與命令放在同一行,如下所示:

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

好,現在你已經創建了第一個提交!可以看到,提交後它會告訴你,當前是在哪個分支(master)提交的,本次提交的完整 SHA-1 校驗和是什麼(463dc4f),以及在本次提交中,有多少文件修訂過,多少行添加和刪改過。

請記住,提交時記錄的是放在暫存區域的快照。任何還未暫存的仍然保持已修改狀態,可以在下次提交時納入版本管理。每一次運行提交操作,都是對你項目作一次快照,以後可以回到這個狀態,或者進行比較。

跳過使用暫存區域

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

$ git status
On branch master
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: CONTRIBUTING.md

no changes added to commit (use “git add” and/or “git commit -a”)
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
1 file changed, 5 insertions(+), 0 deletions(-)

移除文件

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

如果只是簡單地從工作目錄中手工刪除文件,運行 git status 時就會在 “Changes not staged for commit” 部分(也就是 未暫存清單)看到:

$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    PROJECTS.md

no changes added to commit (use "git add" and/or "git commit -a")

然後再運行 git rm 記錄此次移除文件的操作:

$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    PROJECTS.md

下一次提交時,該文件就不再納入版本管理了。如果刪除之前修改過並且已經放到暫存區域的話,則必須要用強制刪除選項 -f(譯註:即 force 的首字母)。這是一種安全特性,用於防止誤刪還沒有添加到快照的數據,這樣的數據不能被 Git 恢復。

另外一種情況是,我們想把文件從 Git 倉庫中刪除(亦即從暫存區域移除),但仍然希望保留在當前工作目錄中。換句話說,你想讓文件保留在磁盤,但是並不想讓 Git 繼續跟蹤。當你忘記添加 .gitignore 文件,不小心把一個很大的日誌文件或一堆 .a 這樣的編譯生成文件添加到暫存區時,這一做法尤其有用。爲達到這一目的,使用 –cached 選項:

$ git rm --cached README

git rm 命令後面可以列出文件或者目錄的名字,也可以使用 glob 模式。比方說:

$ git rm log/\*.log

注意到星號 * 之前的反斜槓 \,因爲 Git 有它自己的文件模式擴展匹配方式,所以我們不用 shell 來幫忙展開。此命令刪除 log/ 目錄下擴展名爲 .log 的所有文件。類似的比如:

$ git rm \*~

該命令爲刪除以 ~ 結尾的所有文件。

移動文件

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

既然如此,當你看到 Git 的 mv 命令時一定會困惑不已。要在 Git 中對文件改名,可以這麼做:

$ git mv file_from file_to

查看日誌

$ git log

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <[email protected]>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <[email protected]>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <[email protected]>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

默認不用任何參數的話,git log 會按提交時間列出所有的更新,最近的更新排在最上面。正如你所看到的,這個命令會列出每個提交的 SHA-1 校驗和、作者的名字和電子郵件地址、提交時間以及提交說明。

一個常用的選項是 -p,用來顯示每次提交的內容差異。你也可以加上 -2 來僅顯示最近兩次提交:

$ git log -p -2

如果你想看到每次提交的簡略的統計信息,你可以使用 –stat 選項:

$ git log --stat

–stat 選項在每次提交的下面列出額所有被修改過的文件、有多少文件被修改了以及被修改過的文件的哪些行被移除或是添加了。在每次提交的最後還有一個總結。

還有個常用的 –pretty 選項,可以指定使用完全不同於默認格式的方式展示提交歷史。
比如用 –oneline 將每個提交放在一行顯示,這在提交數很大時非常有用。另外還有 short,full 和 fuller 可以用,展示的信息或多或少有些不同

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

但最有意思的是 format,可以定製要顯示的記錄格式。這樣的輸出對後期提取分析格外有用 — 因爲你知道輸出的格式不會隨着Git的更新而發生改變:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit
Table 2-1. git log --pretty=format 常用的選項
選項說明

%H

提交對象(commit)的完整哈希字串

%h

提交對象的簡短哈希字串

%T

樹對象(tree)的完整哈希字串

%t

樹對象的簡短哈希字串

%P

父對象(parent)的完整哈希字串

%p

父對象的簡短哈希字串

%an

作者(author)的名字

%ae

作者的電子郵件地址

%ad

作者修訂日期(可以用 –date= 選項定製格式)

%ar

作者修訂日期,按多久以前的方式顯示

%cn

提交者(committer)的名字

%ce

提交者的電子郵件地址

%cd

提交日期

%cr

提交日期,按多久以前的方式顯示

%s

提交說明

當 oneline 或 format 與另一個 log 選項 –graph 結合使用時尤其有用。這個選項添加了一些ASCII字符串來形象地展示你的分支、合併歷史:

Table 2-2. 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(後跟指定格式)。

限制輸出長度

Table 2-3. 限制 git log 輸出的選項
選項說明

-(n)

僅顯示最近的 n 條提交

--since, --after

僅顯示指定時間之後的提交。

--until, --before

僅顯示指定時間之前的提交。

--author

僅顯示指定作者相關的提交。

--committer

僅顯示指定提交者相關的提交。

--grep

僅顯示含指定關鍵字的提交

-S

僅顯示添加或移除了某個關鍵字的提交

來看一個實際的例子,如果要查看 Git 倉庫中,2008 年 10 月期間,Junio Hamano 提交的但未合併的測試文件,可以用下面的查詢命令:

$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch 

在近40000條提交中,上面的輸出僅列出了符合條件的6條記錄。

撤消操作

撤消操作

有時候我們提交完了才發現漏掉了幾個文件沒有添加,或者提交信息寫錯了。此時,可以運行帶有 –amend 選項的提交命令嘗試重新提交:

$ git commit --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)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

在 “Changes to be committed” 文字正下方,提示使用 git reset HEAD <file>... 來取消暫存。所以,我們可以這樣來取消暫存 CONTRIBUTING.md 文件:

$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M   CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

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:   CONTRIBUTING.md

這個命令有點兒奇怪,但是起作用了。CONTRIBUTING.md 文件已經是修改未暫存的狀態了。

雖然在調用時加上 –hard 選項可以令 git reset 成爲一個危險的命令(譯註:可能導致工作目錄中所有當前進度丟失!),但本例中工作目錄內的文件並不會被修改。不加選項地調用 git reset 並不危險 — 它只會修改暫存區域。

撤消對文件的修改

如果你並不想保留對 CONTRIBUTING.md 文件的修改怎麼辦?你該如何方便地撤消修改 - 將它還原成上次提交時的樣子(或者剛克隆完的樣子,或者剛把它放入工作目錄時的樣子)?幸運的是,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:   CONTRIBUTING.md

它非常清楚地告訴了你如何撤消之前所做的修改。讓我們來按照提示執行:

$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

可以看到那些修改已經被撤消了。

你需要知道 git checkout – [file] 是一個危險的命令,這很重要。你對那個文件做的任何修改都會消失 - 你只是拷貝了另一個文件來覆蓋它。除非你確實清楚不想要那個文件了,否則不要使用這個命令。

遠程倉庫的使用

查看遠程倉庫

如果想查看你已經配置的遠程倉庫服務器,可以運行 git remote 命令。它會列出你指定的每一個遠程服務器的簡寫。如果你已經克隆了自己的倉庫,那麼至少應該能看到 origin - 這是 Git 給你克隆的倉庫服務器的默認名字:

$ git remote
origin

你也可以指定選項 -v,會顯示需要讀寫遠程倉庫使用的 Git 保存的簡寫與其對應的 URL。

$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)

如果你的遠程倉庫不止一個,該命令會將它們全部列出。

添加遠程倉庫

運行 git remote add <shortname> <url> 添加一個新的遠程 Git 倉庫,同時指定一個你可以輕鬆引用的簡寫:

$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)

現在你可以在命令行中使用字符串 pb 來代替整個 URL。例如,如果你想拉取 Paul 的倉庫中有但你沒有的信息,可以運行 git fetch pb:

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

現在 Paul 的 master 分支可以在本地通過 pb/master 訪問到 - 你可以將它合併到自己的某個分支中,或者如果你想要查看它的話,可以檢出一個指向該點的本地分支。

從遠程倉庫中抓取與拉取

從遠程倉庫中獲得數據,可以執行:

$ git fetch [remote-name]

這個命令會訪問遠程倉庫,從中拉取所有你還沒有的數據。執行完成後,你將會擁有那個遠程倉庫中所有分支的引用,可以隨時合併或查看。

如果你使用 clone 命令克隆了一個倉庫,命令會自動將其添加爲遠程倉庫並默認以 “origin” 爲簡寫。所以,git fetch origin 會抓取克隆(或上一次抓取)後新推送的所有工作。必須注意 git fetch 命令會將數據拉取到你的本地倉庫 - 它並不會自動合併或修改你當前的工作。當準備好時你必須手動將其合併入你的工作。

推送到遠程倉庫

當你想分享你的項目時,必須將其推送到上游。這個命令很簡單:git push [remote-name] [branch-name]。當你想要將 master 分支推送到 origin 服務器時(再次說明,克隆時通常會自動幫你設置好那兩個名字),那麼運行這個命令就可以將你所做的備份到服務器:

$ git push origin master

只有當你有所克隆服務器的寫入權限,並且之前沒有人推送過時,這條命令才能生效。當你和其他人在同一時間克隆,他們先推送到上游然後你再推送到上游,你的推送就會毫無疑問地被拒絕。你必須先將他們的工作拉取下來並將其合併進你的工作後才能推送。

查看遠程倉庫

如果想要查看某一個遠程倉庫的更多信息,可以使用 git remote show [remote-name] 命令。如果想以一個特定的縮寫名運行這個命令,例如 origin,會得到像下面類似的信息:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

它同樣會列出遠程倉庫的 URL 與跟蹤分支的信息。這些信息非常有用,它告訴你正處於 master 分支,並且如果運行 git pull,就會抓取所有的遠程引用,然後將遠程 master 分支合併到本地 master 分支。它也會列出拉取到的所有遠程引用。

這是一個經常遇到的簡單例子。如果你是 Git 的重度使用者,那麼還可以通過 git remote show 看到更多的信息。

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

這個命令列出了當你在特定的分支上執行 git push 會自動地推送到哪一個遠程分支。它也同樣地列出了哪些遠程分支不在你的本地,哪些遠程分支已經從服務器上移除了,還有當你執行 git pull 時哪些分支會自動合併。

遠程倉庫的移除與重命名

如果想要重命名引用的名字可以運行 git remote rename 去修改一個遠程倉庫的簡寫名。例如,想要將 pb 重命名爲 paul,可以用 git remote rename 這樣做:

$ git remote rename pb paul

值得注意的是這同樣也會修改你的遠程分支名字。那些過去引用 pb/master 的現在會引用 paul/master。

如果因爲一些原因想要移除一個遠程倉庫 - 你已經從服務器上搬走了或不再想使用某一個特定的鏡像了,又或者某一個貢獻者不再貢獻了 - 可以使用 git remote rm :

$ git remote rm paul

打標籤

列出標籤

$ git tag

這個命令以字母順序列出標籤;但是它們出現的順序並不重要。

你也可以使用特定的模式查找標籤。例如:1.8.5 系列

$ git tag -l 'v1.8.5*'

創建標籤

Git 使用兩種主要類型的標籤:輕量標籤(lightweight)與附註標籤(annotated)。

一個輕量標籤很像一個不會改變的分支 - 它只是一個特定提交的引用。

然而,附註標籤是存儲在 Git 數據庫中的一個完整對象。它們是可以被校驗的;其中包含打標籤者的名字、電子郵件地址、日期時間;還有一個標籤信息;並且可以使用 GNU Privacy Guard (GPG)簽名與驗證。通常建議創建附註標籤,這樣你可以擁有以上所有信息;但是如果你只是想用一個臨時的標籤,或者因爲某些原因不想要保存那些信息,輕量標籤也是可用的。

附註標籤

在 Git 中創建一個附註標籤是很簡單的。最簡單的方式是當你在運行 tag 命令時指定 -a 選項:

$ git tag -a v1.4 -m 'my version 1.4'

-m 選項指定了一條將會存儲在標籤中的信息。如果沒有爲附註標籤指定一條信息,Git 會運行編輯器要求你輸入信息。

通過使用 git show 命令可以看到標籤信息與對應的提交信息:

$ git show v1.4
tag v1.4
Tagger: Ben Straub <ben@straub.cc>
Date:   Sat May 3 20:19:12 2014 -0700

my version 1.4

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

    changed the version number

輸出顯示了打標籤者的信息、打標籤的日期時間、附註信息,然後顯示具體的提交信息。

輕量標籤

另一種給提交打標籤的方式是使用輕量標籤。輕量標籤本質上是將提交校驗和存儲到一個文件中 - 沒有保存任何其他信息。創建輕量標籤,不需要使用 -a、-s 或 -m 選項,只需要提供標籤名字:

$ git tag v1.4-lw

這時,如果在標籤上運行 git show,你不會看到額外的標籤信息。命令只會顯示出提交信息:

$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <[email protected]>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

後期打標籤

你也可以對過去的提交打標籤。假設提交歷史是這樣的:

$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme

現在,假設在 v1.2 時你忘記給項目打標籤,也就是在 “updated rakefile” 提交。你可以在之後補上標籤。要在那個提交上打標籤,你需要在命令的末尾指定提交的校驗和(或部分校驗和):

$ git tag -a v1.2 9fceb02

可以看到你已經在那次提交上打上標籤了:

$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5

$ git show v1.2
tag v1.2
Tagger: Scott Chacon <[email protected]>
Date:   Mon Feb 9 15:32:16 2009 -0800

version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <[email protected]>
Date:   Sun Apr 27 20:43:35 2008 -0700

    updated rakefile
...

共享標籤

默認情況下,git push 命令並不會傳送標籤到遠程倉庫服務器上。在創建完標籤後你必須顯式地推送標籤到共享服務器上。這個過程就像共享遠程分支一樣 - 你可以運行 git push origin [tagname]

$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To [email protected]:schacon/simplegit.git
 * [new tag]         v1.5 -> v1.5

如果想要一次性推送很多標籤,也可以使用帶有 –tags 選項的 git push 命令。這將會把所有不在遠程倉庫服務器上的標籤全部傳送到那裏。

$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.4 -> v1.4
 * [new tag]         v1.4-lw -> v1.4-lw

現在,當其他人從倉庫中克隆或拉取,他們也能得到你的那些標籤。

檢出標籤

在 Git 中你並不能真的檢出一個標籤,因爲它們並不能像分支一樣來回移動。如果你想要工作目錄與倉庫中特定的標籤版本完全一樣,可以使用 git checkout -b [branchname] [tagname] 在特定的標籤上創建一個新分支:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

當然,如果在這之後又進行了一次提交,version2 分支會因爲改動向前移動了,那麼 version2 分支就會和 v2.0.0 標籤稍微有些不同,這時就應該當心了。

Git 別名

Git 並不會在你輸入部分命令時自動推斷出你想要的命令。如果不想每次都輸入完整的 Git 命令,可以通過 git config 文件來輕鬆地爲每一個命令設置一個別名。這裏有一些例子你可以試試:

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.unstage 'reset HEAD --'
$ git config --global alias.last 'log -1 HEAD'

這會使下面的兩個命令等價:

$ git unstage fileA
$ git reset HEAD -- fileA

查看到最後一次提交:

$ git last

Git 只是簡單地將別名替換爲對應的命令。然而,你可能想要執行外部命令,而不是一個 Git 子命令。如果是那樣的話,可以在命令前面加入 ! 符號。如果你自己要寫一些與 Git 倉庫協作的工具的話,那會很有用。我們現在演示將 git visual 定義爲 gitk 的別名:

$ git config --global alias.visual '!gitk'


原文出處:https://www.git-scm.com/book/

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