我把git想簡單了

git 是開源的分佈式版本控制系統,能夠有效、高速地處理從很小到很是大的項目版本管理。咱們平時可能常用它,可是你真的瞭解 git 嗎?先拋幾個問題 git add 發生了什麼?git 有哪些暫存區?git pullgit fetch 區別?git mergegit rebase 區別?git resetget restore 區別?html

雖然,我一直在用 git ,像上面這些問題,我就不知道,因此將它們總結下。原文在我的博客git

什麼是版本控制系統

開篇說了 git 是一個分佈式的版本控制系統,那麼什麼是版本控制系統呢?能夠參考 廖雪峯舉的例子 Word 文檔操做微信

Word 文檔操做舉例,當你想要 刪除 某一段落的時候,又怕未來想要 恢復 找不到怎麼辦?你可能,會保存一個 副本。接着再修改,再保存一個 副本,這樣一直持續,將會有好幾個 副本分佈式

過了一週,你想找到某一段,可能須要從這些 副本 中,一個一個查找,是否是很麻煩。工具

這仍是你一我的寫 Word 的狀況,假如,你的同事和你一塊兒編輯這個 Word,爲了保證文檔同步,大家之間可能須要不停的相互發送傳遞(經過 U盤,或者 qq 微信 等方式)。總之,很繁瑣。fetch

那假如說有這樣一個軟件,能夠記錄每次修改,並且還能夠和多人共同編輯,是否是很方便。git 就是解決相似上面的問題,方便咱們查看每次修改內容,以及同步別人的修改等。動畫

基本操做

  • git clone 通常來講,經過 git 來進行遠程操做的第一步,是經過此命令從遠程主機上克隆一個版本庫
  • git fecth 將某個遠程主機的更新,所有取回本地
  • git pull 取回遠程主機某個分支的更新,再與本地的指定分支合併 smartgit pull 按鈕有個下拉選項,能夠選擇: Merge fetched remote changes Rebase local branch onto fetched changes
  • git add 添加文件。細分來講,應該是將工做區中的文件差別提交至暫存區。 至關於 smartgitstage
  • git commit 提交文件。將暫存區中的修改,提交到本地分支。每次提交會產生一個 commit-id,而且會帶上你的 username email 等信息。
  • git push 將本地分支的更新,推送到遠程主機
  • git marge 合併分之,多條線
  • git rebase <name> 合併某分支到當前分之,變基 衍合,一條線
  • git branch <name> 建立分支 git branch -d 刪除分支
  • git checkout git checkout <name> 切換分支 git checkout -b <name> 建立 並 切換 分支。 git checkout -- <file> 放棄更改。(不加 -- 也能夠放棄更改) 至關於 smartgitunstage
  • git reset HEAD <file> 取消添加暫存區
  • git switch <name> 切換分支,新版本提供的命令。 git switch -c <name> 建立並切換

借一張圖網站

工做區,暫存區,本地倉庫,遠程倉庫

工做區就是咱們 克隆 clone 一個項目,這個項目就是 工做區;當執行 git add 時,會將改動添加到某個地方,這個地方就是暫存區本地倉庫,由 .git 目錄管理;遠程倉庫,就是拉取的地址。他們之間的關係以下面兩張圖所示:spa

HEAD

HEADgit 內部的一個指針,指向當前版本。這個當前版本包含兩個概念 分支提交HEAD 負責指向哪條 分支,而 分支 指向某次具體 提交.net

默認狀況

建立新分支。Git建立一個分支很快,由於除了增長一個dev指針,改改HEAD的指向,工做區的文件都沒有任何變化。從如今開始,對工做區的修改和提交就是針對dev分支了,好比新提交一次後,dev指針往前移動一步,而master指針不變。

合併分支。首先切到 master ,而後 將 dev 合併到當前分支。就是直接把 master 指向 dev 的當前提交。git 很懶,這個提交方式 是由於 git 嘗試採用 fast-forward (—ff) 這類合併不會建立新的提交。

若是 master 上沒有修改,這個時候狀況就是這樣的。若是 master 上修改,將會採用 No-fast-foward (—no-ff),會建立一個 merge 提交。

刪除分支。開發完分以後,能夠視狀況將其刪除。刪除dev分支就是把dev指針給刪掉

動畫演示 以下:

git pull 與 git fetch

git pullgit fetch 均可以從遠程倉庫中拉取最新代碼。不一樣之處在於更新的方式不一樣。

git fetch

git fetch 方式,是將遠程主機的最新內容拉到本地,用戶在檢查了之後決定是否合併到工做本機分支中。最新的更新記錄會保存在 .git/FETCH_HEAD 文件中。

git pull

git pull 則是將遠程主機的最新內容拉下來後直接合並,這樣可能會產生衝突,須要手動解決。git pull = git fetch +git merge

注意,不必定是 git merge 也能夠選擇 git rebase,好比,我用的 smartgit:

git merge 與 git rebase

git mergegit rebase 都是用來合併分之的。不一樣之處,在於生成的 log 分叉線不一樣。

git merge 會把公共分支和你當前的commit 合併在一塊兒,造成一個新的 commit 提交。

git rebase 會把你當前分支的 commit 放到公共分支的最後面,因此叫變基。就好像你從公共分支又從新拉出來這個分支同樣。

假設,你有以下分支記錄,

假設在 master 分支上的新提交與你正在開發的 feature 相關。須要將新提交合併到你的 feature 分支中,你能夠有兩個選擇:merge 或者 rebase

git merge 方式

git checkout feature
git merge master

# 或者一條命令。前提是你得在 feature 分支上
git merge feature master 
複製代碼

如上圖所示,這會在 feature 分支中建立一個新的 merge commit,它將兩個分支的歷史聯繫在一塊兒。

使用 merge 是很好的方式,由於它是一種 非破壞性的 操做。現有分支不會以任何方式被更改。這避免了 rebase 操做所產生的潛在缺陷。

缺點是會產生一個額外的提交。

git rebase 方式

git checkout feature
git rebase master
複製代碼

如上圖所示,這會將整個 feature 分支移動到 master 分支的頂端,從而有效地整合了全部 master 分支上的提交。可是,與 merge 提交方式不一樣,rebase 經過爲原始分支中的每一個提交建立全新的 commits重寫 項目歷史記錄。

rebase 的主要好處是能夠得到更清晰的項目歷史。

git rebase 黃金法則

git rebase 的黃金法則是 永遠不要在公共分支上使用它

什麼是 公共分支呢。個人理解是想 master dev test 這樣的分之,或者說是有兩我的以上使用的分支,就叫公共分支。

你 rebase master 分支到 feature 分支之上會發生什麼:

git reset 與 get revert

git resetget revert 均可用於版本回退,區別在於,一個能夠硬重置,不保留記錄;一個是覆蓋式提交,保留記錄。

先假設咱們有這樣的分支:

git reset

git reset 分爲 軟重置(git reset --soft <commit id>) 和 硬重置(git reset --head <commit id>)。默認爲 軟重置,通常在回滾代碼的時候,咱們用的是 硬重置

git reset --hard <commit id>
git push -f
複製代碼

git revert

git revert 還原,經過對特定的提交執行還原操做,咱們會建立一個包含已還原修改的新提交

git 練習

發現一個很好的瞭解Git 基本概念和操做的工具,Git Online 。這個網站經過一個個任務讓你瞭解 git,若是不想作題,能夠直接加參數 NODEMO Git Online 沙盒模式,來在線驗證。

若是,還想經過動圖的方式,直觀的瞭解 git 命令是如何工做了,可參考我轉載的這篇文章 CS可視化:有用的Git命令

參考連接

Git 教程

一個小時學會Git

git rebase VS git merge? 更優雅的 git 合併方式值得擁有

Git恢復以前版本的兩種方法reset、revert(圖文詳解)

相關文章
相關標籤/搜索