版本控制git之一-倉庫管理

git

​ 再開始這個話題之前,讓我想起了一件很痛苦的事情,在我大學寫畢業論文的時候,我當時的文件是這樣保存的

畢業論文_初稿.doc
畢業論文_修改1.doc
畢業論文_修改2.doc
畢業論文_修改3.doc
畢業論文_完整版1.doc
畢業論文_完整版2.doc
畢業論文_完整版3.doc
畢業論文_死也不改版.doc
畢業論文_最終版1.doc
畢業論文_最終版2.doc

​ 這個時候,我們會重複的提交給導師,導師也會幫我們修改畢業論文,我自己這裏的還好說,那麼如果是導師再給我返回回來的文件,我就要想想,我是什麼時候提交給導師的,我要把我後面寫的東西跟導師寫的東西都添加到我的最新的版本中

以上就是使用最原始的方式進行版本控制,但是這種方式有顯著缺點:

  • 多個文件,保留所有版本時,需要爲每個版本保存一個文件...
  • 協同操作,多人協同操作時,需要將文件打包發來發去...
  • 容易丟失,被刪除意味着永遠失去...(可以選擇網盤)

​ 這個時候我就想,如果能有一個軟件來幫助我來解決這個問題的話,那是多麼好的一件事啊,這樣我自己就不需要去保存所有的文件了,什麼時候需要直接在軟件裏面看一下,豈不是很方便.

版本 文件名 用戶 說明 日期
1.0版本 畢業論文 張三 新建 2018.1.12
1.1版本 畢業論文 張三 寫了第一部分 2018.2.12
2.0版本 畢業論文 張三 寫完了全部 2018.3.23
3.0版本 畢業論文 張三 答辯使用 2018.4.25

這樣你就從版本管理的農耕時代直接進入到了版本控制的21世紀,爲了解決以上版本控制存在問題,應運而生了一批版本控制工具:VSS、CVS、SVN、Git等,其中Git屬於絕對霸主地位。

git

Git 是一個開源的分佈式版本控制軟件,用以有效、高速的處理從很小到非常大的項目版本管理。 Git 最初是由Linus Torvalds設計開發的,用於管理Linux內核開發。Git 是根據GNU通用公共許可證版本2的條款分發的自由/免費軟件,安裝參見:http://git-scm.com/

GitHub是一個基於Git的遠程文件託管平臺(同GitCafe、BitBucket和GitLab等)。

Git本身完全可以做到版本控制,但其所有內容以及版本記錄只能保存在本機,如果想要將文件內容以及版本記錄同時保存在遠程,則需要結合GitHub來使用。使用場景:

  • 無GitHub:在本地 .git 文件夾內維護歷時文件
  • 有GitHub:在本地 .git 文件夾內維護歷時文件,同時也將歷時文件託管在遠程倉庫

其他:

​ 集中式:遠程服務器保存所有版本,用戶客戶端有某個版本
​ 分佈式:遠程服務器保存所有版本,用戶客戶端有所有版本

安裝

在 Linux 上安裝

如果你想在 Linux 上用二進制安裝程序來安裝 Git,可以使用發行版包含的基礎軟件包管理工具來安裝。 如果以 Fedora 上爲例,你可以使用 yum:

  $ sudo yum install git

如果你在基於 Debian 的發行版上,請嘗試用 apt-get:

  $ sudo apt-get install git

在 Mac 上安裝

在 Mac 上安裝 Git 有多種方式。 最簡單的方法是安裝 Xcode Command Line Tools。 Mavericks (10.9) 或更高版本的系統中,在 Terminal 裏嘗試首次運行 git 命令即可。 如果沒有安裝過命令行開發者工具,將會提示你安裝。

如果你想安裝更新的版本,可以使用二進制安裝程序。 官方維護的 OSX Git 安裝程序可以在 Git 官方網站下載,網址爲 <http://git-scm.com/download/mac&gt;。

在 Windows 上安裝

在 Windows 上安裝 Git 也有幾種安裝方法。 官方版本可以在 Git 官方網站下載。 打開 <http://git-scm.com/download/win>,下載會自動開始。 要注意這是一個名爲 Git for Windows的項目(也叫做 msysGit),和 Git 是分別獨立的項目;更多信息請訪問 <http://msysgit.github.io/&gt;。

另一個簡單的方法是安裝 GitHub for Windows。 該安裝程序包含圖形化和命令行版本的 Git。 它也能支持 Powershell,提供了穩定的憑證緩存和健全的 CRLF 設置。 稍後我們會對這方面有更多瞭解,現在只要一句話就夠了,這些都是你所需要的。 你可以在 GitHub for Windows 網站下載,網址爲 http://windows.github.com

命令行

Git 有多種使用方式。 你可以使用原生的命令行模式,也可以使用 GUI 模式,這些 GUI 軟件也能提供多種功能。 在本書中,我們將使用命令行模式。 這是因爲首先,只有在命令行模式下你才能執行 Git 的 所有命令,而大多數的 GUI 軟件只實現了 Git 所有功能的一個子集以降低操作難度。 如果你學會了在命令行下如何操作,那麼你在操作 GUI 軟件時應該也不會遇到什麼困難,但是,反之則不成立。 此外,由於每個人的想法與側重點不同,不同的人常常會安裝不同的 GUI 軟件,但 所有 人一定會有命令行工具。

假如你是 Mac 用戶,我們希望你懂得如何使用終端(Terminal);假如你是 Windows 用戶,我們希望你懂得如何使用命令窗口(Command Prompt)或 PowerShell。 如果你尚未掌握以上技能,我們建議你先停下來快速學習一下,本書中的講述和舉例將用到這些技能。

git基礎

獲取 Git 倉庫

在現有目錄中初始化倉庫

如果你打算使用 Git 來對現有的項目進行管理,你只需要進入該項目目錄並輸入:

[Derek@git]$ git init

該命令將創建一個名爲 .git 的子目錄,這個子目錄含有你初始化的 Git 倉庫中所有的必須文件。 但是,在這個時候,我們僅僅是做了一個初始化的操作,你的項目裏的文件還沒有被跟蹤。

那麼怎麼來實現項目中的管理那?

和把大象放到冰箱需要3步相比,把一個文件放到Git倉庫只需要兩步。

第一步,用命令git add告訴Git,把文件添加到倉庫:

[Derek@git]$ git add readme.txt

執行上面的命令,沒有任何顯示,這就對了,Unix的哲學是“沒有消息就是好消息”,說明添加成功。

第二步,用命令git commit告訴Git,把文件提交到倉庫:

[Derek@git]$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

簡單解釋一下git commit命令,-m後面輸入的是本次提交的說明,可以輸入任意內容,當然最好是有意義的,這樣你就能從歷史記錄裏方便地找到改動記錄。

嫌麻煩不想輸入-m "xxx"行不行?確實有辦法可以這麼幹,但是強烈不建議你這麼幹,因爲輸入說明對自己對別人閱讀都很重要。實在不想輸入說明的童鞋請自行Google,我不告訴你這個參數。

git commit命令執行成功後會告訴你,1 file changed:1個文件被改動(我們新添加的readme.txt文件);2 insertions:插入了兩行內容(readme.txt有兩行內容)。

記錄每次更新到倉庫

我們已經成功地添加並提交了一個readme.txt文件,現在,是時候繼續工作了,於是,我們繼續修改readme.txt文件,改成如下內容:

Git is a distributed version control system.
Git is free software.

現在,運行git status命令看看結果:

[Derek@git]$ 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:   readme.txt

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

git status命令可以讓我們時刻掌握倉庫當前的狀態,上面的命令輸出告訴我們,readme.txt被修改過了,但還沒有準備提交的修改。

查看已暫存和未暫存的修改

如果 git status 命令的輸出對於你來說過於模糊,你想知道具體修改了什麼地方,可以用 git diff命令。 稍後我們會詳細介紹 git diff,你可能通常會用它來回答這兩個問題:當前做的哪些更新還沒有暫存? 有哪些更新已經暫存起來準備好了下次提交? 儘管 git status 已經通過在相應欄下列出文件名的方式回答了這個問題,git diff 將通過文件補丁的格式顯示具體哪些行發生了改變。

[Derek@git]$ git diff
diff --git a/README.md b/README.md
index e69de29..a34691f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@
+this is new line

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

若要查看已暫存的將要添加到下次提交裏的內容,可以用 git diff --cached 命令。(Git 1.6.1 及更高版本還允許使用 git diff --staged,效果是相同的,但更好記些。)

[Derek@git]$ git diff  --staged
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29

提交更新

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

[Derek@git]$ git commit

-m 選項,將提交信息與命令放在同一行

[Derek@git]$ git commit -m 'create'
[master (root-commit) 88a09aa] create
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md

跳過使用暫存區域

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

[Derek@git]git commit -a -m  'update'
[master 86d801b] update
 1 file changed, 1 insertion(+)

查看提交歷史

[Derek@git]$ git log
commit 86d801bbaa4cc560acc7c8f79a65cac85201f170 (HEAD -> master)
Author: wangfeng7399 <[email protected]>
Date:   Tue Feb 19 18:48:48 2019 +0800

    update

commit 88a09aa009af29e9a784d6dbb68589f70f1c51be
Author: wangfeng7399 <[email protected]>
Date:   Tue Feb 19 18:48:04 2019 +0800

    create

-p 用來顯示每次提交的內容差異

你也可以加上 -2 來僅顯示最近兩次提交

[Derek@git]git log -p -2
commit 86d801bbaa4cc560acc7c8f79a65cac85201f170 (HEAD -> master)
Author: wangfeng7399 <[email protected]>
Date:   Tue Feb 19 18:48:48 2019 +0800

    update

diff --git a/README.md b/README.md
index e69de29..a34691f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@
+this is new line

commit 88a09aa009af29e9a784d6dbb68589f70f1c51be
Author: wangfeng7399 <[email protected]>
Date:   Tue Feb 19 18:48:04 2019 +0800

    create

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29

另外一個常用的選項是 --pretty。 這個選項可以指定使用不同於默認格式的方式展示提交歷史。 這個選項有一些內建的子選項供你使用。 比如用 oneline 將每個提交放在一行顯示,查看的提交數很大時非常有用。 另外還有 shortfullfuller 可以用,展示的信息或多或少有些不同,請自己動手實踐一下看看效果如何。

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

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

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 提交說明

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

限制 git log 輸出的選項 中列出了常用的選項

選項 說明
-(n) 僅顯示最近的 n 條提交
--since, --after 僅顯示指定時間之後的提交。
--until, --before 僅顯示指定時間之前的提交。
--author 僅顯示指定作者相關的提交。
--committer 僅顯示指定提交者相關的提交。
--grep 僅顯示含指定關鍵字的提交
-S 僅顯示添加或移除了某個關鍵字的提交

取消暫存的文件

例如,你已經修改了兩個文件並且想要將它們作爲兩次獨立的修改提交,但是卻意外地輸入了 git add * 暫存了它們兩個。 如何只取消暫存兩個中的一個呢? git status 命令提示了你:

[Derek@git]git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   README.md
[Derek@git]git reset HEAD README.md
Unstaged changes after reset:
M   README.md
[Derek@git]$ 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:   README.md

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

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

撤消對文件的修改

如果你並不想保留對 README.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:   README.md

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

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

    renamed:    README.md -> README

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

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

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