版本控制git之一-倉庫管理
git
再開始這個話題以前,讓我想起了一件很痛苦的事情,在我大學寫畢業論文的時候,我當時的文件是這樣保存的git
畢業論文_初稿.doc 畢業論文_修改1.doc 畢業論文_修改2.doc 畢業論文_修改3.doc 畢業論文_完整版1.doc 畢業論文_完整版2.doc 畢業論文_完整版3.doc 畢業論文_死也不改版.doc 畢業論文_最終版1.doc 畢業論文_最終版2.doc
這個時候,咱們會重複的提交給導師,導師也會幫咱們修改畢業論文,我本身這裏的還好說,那麼若是是導師再給我返回回來的文件,我就要想一想,我是何時提交給導師的,我要把我後面寫的東西跟導師寫的東西都添加到個人最新的版本中github
以上就是使用最原始的方式進行版本控制,可是這種方式有顯著缺點:sql
- 多個文件,保留全部版本時,須要爲每一個版本保存一個文件...
- 協同操做,多人協同操做時,須要將文件打包發來發去...
- 容易丟失,被刪除意味着永遠失去...(能夠選擇網盤)
這個時候我就想,若是能有一個軟件來幫助我來解決這個問題的話,那是多麼好的一件事啊,這樣我本身就不須要去保存全部的文件了,何時須要直接在軟件裏面看一下,豈不是很方便.shell
版本 | 文件名 | 用戶 | 說明 | 日期 |
---|---|---|---|---|
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屬於絕對霸主地位。windows
git
Git 是一個開源的分佈式版本控制軟件,用以有效、高速的處理從很小到很是大的項目版本管理。 Git 最初是由Linus Torvalds設計開發的,用於管理Linux內核開發。Git 是根據GNU通用公共許可證版本2的條款分發的自由/免費軟件,安裝參見:http://git-scm.com/緩存
GitHub是一個基於Git的遠程文件託管平臺(同GitCafe、BitBucket和GitLab等)。ruby
Git自己徹底能夠作到版本控制,但其全部內容以及版本記錄只能保存在本機,若是想要將文件內容以及版本記錄同時保存在遠程,則須要結合GitHub來使用。使用場景:bash
- 無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>;。
在 Windows 上安裝
在 Windows 上安裝 Git 也有幾種安裝方法。 官方版本能夠在 Git 官方網站下載。 打開 <http://git-scm.com/download/win>,下載會自動開始。 要注意這是一個名爲 Git for Windows的項目(也叫作 msysGit),和 Git 是分別獨立的項目;更多信息請訪問 <http://msysgit.github.io/>;。
另外一個簡單的方法是安裝 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 <wangfeng17399@163.com> Date: Tue Feb 19 18:48:48 2019 +0800 update commit 88a09aa009af29e9a784d6dbb68589f70f1c51be Author: wangfeng7399 <wangfeng17399@163.com> Date: Tue Feb 19 18:48:04 2019 +0800 create
-p 用來顯示每次提交的內容差別
你也能夠加上 -2
來僅顯示最近兩次提交
[Derek@git]git log -p -2 commit 86d801bbaa4cc560acc7c8f79a65cac85201f170 (HEAD -> master) Author: wangfeng7399 <wangfeng17399@163.com> 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 <wangfeng17399@163.com> 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
將每一個提交放在一行顯示,查看的提交數很大時很是有用。 另外還有 short
,full
和 fuller
能夠用,展現的信息或多或少有些不一樣,請本身動手實踐一下看看效果如何。
[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]
是一個危險的命令,這很重要。 你對那個文件作的任何修改都會消失 - 你只是拷貝了另外一個文件來覆蓋它。 除非你確實清楚不想要那個文件了,不然不要使用這個命令。