Git 的全面解讀

版本控制

什麼是版本控制

咱們爲何要關心它呢?版本控制是一種記錄一個或若干文 件內容變化,以便未來查閱特定版本修訂狀況的系統html

爲何要使用版本控制

軟件開發中採用版本控制系統是個明智的選擇。 有了它你就能夠將某個文件回溯到以前的狀態,甚至將整個項目都回退到過去某 個時間點的狀態。就算你亂來一氣把整個項目中的文件改的改刪的刪,你也照樣能夠 輕鬆恢復到原先的樣子。但額外增長的工做量卻微乎其微。 你能夠比較文件的變化細節,查出最後是誰修改了哪一個地方,從而找出致使怪異 問題出現的緣由,又是誰在什麼時候報告了某個功能缺陷等等。node

集中化版本控制

優勢:每一個人均可以在必定程度上看到項目中的其 他人正在作些什麼。而管理員也能夠輕鬆掌控每一個開發者的權限,而且管理一個集 中化的版本控制系統; 要遠比在各個客戶端上維護本地數據庫來得輕鬆容易。linux

缺點:故障時沒法協同工做、寫代碼時不能參考版本代碼和對代碼進行優化。中央服務器有丟失數據的風險,git

分佈式版本控制

客戶端並不僅提取最新版本的文件快照,而是把代碼倉庫完整地鏡像下來。這麼一 來,任何一處協同工做用的服務器發生故障,過後均可以用任何一個鏡像出來的本 地倉庫恢復。由於每一次的提取操做,實際上都是一次對代碼倉庫的完整備份es6

分佈式的版本控制系統在管理項目時 存放的不是項目版本與版本之間 的差別.它存的是索引(所需磁盤空間不多 因此每一個客戶端均可以放下整個 項目的歷史記錄)github

分佈式的版本控制系統出現以後,解決了集中式版本控制系統的缺陷:數據庫

  1. 斷網的狀況下也能夠進行開發(由於版本控制是在本地進行的)
  2. 使用 github 進行團隊協做,哪怕 github 掛了 每一個客戶端保存 的也都是整個完整的項目(包含歷史記錄的!!!)

Git 簡述

Git 簡史

Git 是目前世界上最早進的分佈式版本控制系統。同生活中的許多偉大事件同樣,Git 誕生於一個極富紛爭大舉創新的年代。Linux 內核開源項目有着爲數衆廣的參與者。絕 大多數的 Linux 內核維護工做都花在了提交補丁和保存歸檔的繁雜事務上(1991-2002 年間)。到 2002 年,整個項目組開始啓用分佈式版本控制系統 BitKeeper 來管理和維 護代碼。npm

到了 2005 年,開發 BitKeeper 的商業公司同 Linux 內核開源社區的合做關係結 束,他們收回了無償使用 BitKeeper 的權力。這就迫使 Linux 開源社區(特別是 Linux 的締造者 Linus Torvalds )不得不吸收教訓,只有開發一套屬於本身的版本控制系統才 不至於重蹈覆轍。他們對新的系統制訂了若干目標:json

分支切換速度快,容量小(壓縮),簡單的設計,徹底分佈式vim

對非線性開發模式的強力支持(容許上千個並行開發的分支)

有能力高效管理相似 Linux 內核同樣的超大規模項目(速度和數據量)

自誕生於 2005 年以來,Git 日臻成熟完善,在高度易用的同時,仍然保留着初期設 定的目標。它的速度飛快,極其適合管理大項目,它還有着使人難以置信的非線性分支管理 系統能夠應付各類複雜的項目開發需求。

Git 知識點(重要)

Git 的三個概念

工做區、暫存區、版本庫

Git對象、樹對象、提交對象

本地分支、遠程跟蹤分支、遠程分支

Git 特色

直接記錄快照並不是差別比較

Git 和其它版本控制系統(包括 Subversion 和近似工具)的主要差異在於 Git 對待數據的方法。

近乎全部操做都是本地執行

在 Git 中的絕大多數操做都只須要訪問本地文件和資源,通常不須要來自網絡上其它計算機的信息。

保證完整性

Git 中全部數據在存儲前都計算校驗和,而後以校驗和來引用。 這意味着不可能在 Git 不知情時更改任何文件內容或目錄內容。

通常只添加數據

執行的 Git 操做,幾乎只往 Git 數據庫中增長數據。

三種狀態

已提交(committed)、已修改(modified)和已暫存(staged)

工做流程

每一個項目都有一個 Git 目錄(.git )它是 Git 用來保存元數據和對象數據庫 的地方。

1、在工做目錄中修改某些文件。 從項目中取出某個版本的全部文件和目錄,用以開始後續工做的叫作工做 目錄。這些文件實際上都是從 Git 目錄中的壓縮對象數據庫中提取出來 的,接下來就能夠在工做目錄中對這些文件進行編輯。

2、保存到暫存區域,對暫存區作快照 暫存區域只不過是個簡單的文件,通常都放在 Git 目錄中。有時候人們 會把這個文件叫作索引文件,不過標準說法仍是叫暫存區域。

3、提交更新 將保存在暫存區域的文件快照永久轉儲到本地數據庫(Git 目錄) 中

咱們能夠從文件所處的位置來判斷狀態:若是是 Git 目錄中保存着的特定版 本文件,就屬於已提交狀態;若是做了修改並已放入暫存區域,就屬於已暫存 狀態;若是自上次取出後,做了修改但尚未放到暫存區域,就是已修改狀態。

分支的本質

分支的本質就是一個提交對象,全部的分支都會有機會被HEAD所引用。當咱們有新的提交的時候,HEAD會攜帶當前持有的分支往前移動

遠程協做

三大概念:本地分支、遠程跟蹤分支(remote/分支名)、遠程分支

基本流程

第一步: 項目經理建立一個空的遠程倉庫
第二步: 項目經理建立一個待推送的本地倉庫
第三步: 爲遠程倉庫配別名  配完用戶名 郵箱
第四步: 在本地倉庫中初始化代碼 提交代碼
第五步: 推送
第六步: 邀請成員
第七步: 成員克隆遠程倉庫
第八步: 成員作出修改
第九步: 成員推送本身的修改
第十步: 項目經理拉取成員的修改

克隆倉庫時 會自動爲master作跟蹤

Git 安裝&配置

git 地址 : https://git-scm.com/download/win,下載完安裝包以後,雙擊 exe 安裝包,能夠看到以下圖窗口界面,一直點擊下一步,就安裝完成了

Git Base Here基礎命令

清除屏幕clear

用戶設置

用戶名稱:git config --global user.name "[name]" 用戶郵箱:git config --global user.email [email] 檢查已有的配置信息:git config --list 刪除配置信息: git config --global --unset user.email

/etc/gitconfig 文件:系統中對全部用戶都廣泛適用的配置。若使用 git config 時用 --system 選項,讀寫的就是這個文件。 ~/.gitconfig 文件:用戶目錄下的配置文件只適用於該用戶。若使用 git config 時用 --global 選項,讀寫的就是這個文件。 .git/config 文件:當前項目的 Git 目錄中的配置文件(也就是工做目錄 中的 .git/config 文件)這裏的配置僅僅針對當前項目有效。

Git 底層概念(底層命令)

基礎的 linux 命令

git --version查看版本 clear :清除屏幕 echo 'test content':往控制檯輸出信息 echo 'test content' > test.txt 輸出文件 ll :將當前目錄下的 子文件&子目錄平鋪在控制檯 find 目錄名: 將對應目錄下的子孫文件&子孫目錄平鋪在控制檯 find 目錄名 -type f :將對應目錄下的文件平鋪在控制檯 rm 文件名 : 刪除文件 mv 源文件 重命名文件: 重命名 cat 文件的 url : 查看對應文件的內容 vim 文件的 url(在英文模式下) 按 i 進插入模式 進行文件的編輯 按 esc 鍵&按:鍵 進行命令的執行 q! 強制退出(不保存) wq 保存退出 set nu 設置行號

初始化新倉庫

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

做用:初始化後,在當前目錄下會出現一個名爲 .git 的目錄,全部 Git 須要 的數據和資源都存放在這個目錄中。不過目前,僅僅是按照既有的結構框架初始化 好了裏邊全部的文件和目錄,但咱們尚未開始跟蹤管理項目中的任何一個文件。

.git目錄

hooks 目錄包含客戶端或服務端的鉤子腳本; info 包含一個全局性排除文件 logs 保存日誌信息 objects 目錄存儲全部數據內容; refs 目錄存儲指向數據的提交對象的指針(分支) config 文件包含項目特有的配置選項 description 用來顯示對倉庫的描述信息 HEAD 文件指示目前被檢出的分支 index 文件保存暫存區信息

Git 三大基礎對象

Git對象

向數據庫寫入內容 並返回對應鍵值

命令: echo 'test content' | git hash-object -w --stdin -w 選項指示 hash-object 命令存儲數據對象;若不指定此選項,則 該命令僅返回對應的鍵值 -stdin(standard input)選項則指示該命令從標準輸入讀取內容; 若不指定此選項,則須在命令尾部給出待存儲文件的路徑

存文件:git hash-object -w 文件路徑 返回文件對應鍵值:git hash-object 文件路徑 根據鍵值拉取數據:git cat-file -p [filehash] -p 選項可指示該命令自動判斷內容的類型,併爲咱們顯示格式友好的內容

記住文件的每個版本所對應的 SHA-1 值並不現實,且在 Git 中,文件名並無被保存——咱們僅保存了文件的內容

[注意 ] 當前的操做都是在對本地數據庫進行操做 不涉及暫存區

樹對象

樹對象(tree object),它能解決文件名保存的問題,也容許咱們將多個文件 組織到一塊兒。Git 以一種相似於 UNIX 文件系統的方式存儲內容。全部內容均以 樹對象和數據對象(git 對象)的形式存儲,其中樹對象對應了 UNIX 中的目錄項, 數據對象(git 對象)則大體上對應文件內容。一個樹對象包含了一條或多條記錄(每條記錄含有一個指向 git 對象或者子樹對象的 SHA-1 指針,以及相應的模式、類 型、文件名信息)。一個樹對象也能夠包含另外一個樹對象。

構建樹對象

咱們能夠經過 update-indexwrite-treeread-tree 等命令來構建 樹對像並塞入到暫存區。

利用 update-index 命令 爲 test.txt 文件的首個版本——建立一個 暫存區。並經過 write-tree 命令生成樹對像。 git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt

文件模式: 100644,代表這是一個普通文件 100755,表示一個可執行文件 120000,表示一個符號連接。

--add 選項:由於此前該文件並不在暫存區中 首次須要—add

--cacheinfo 選項:由於將要添加的文件位於 Git 數據庫中,而不是位於當前 目錄下 全部須要—cacheinfo

查看暫存區:git ls-files -s 查看樹對象:git cat-file -p master^{tree}(或者是樹對象的 hash) 暫存區生成樹對象存入庫:git write-tree

新增 new.txt 將 new.txt 和 test.txt 文件的第二個版本塞入暫存區。並經過 write-tree 命令生成樹對像。

echo 'new file' > new.txt
git update-index --cacheinfo 100644 / 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
git update-index --add new.txt git write-tree

將第一個樹對象加入第二個樹對象,使其成爲新的樹對象

git read-tree --prefix=bak 06e21bb0105e2de6c846725a9a7172f57dd1af96

最後的樹對象

如今有三個樹對象(執行了三次 write-tree),分別表明了咱們想要跟蹤 的不一樣項目快照。然而問題依舊:若想重用這些快照,你必須記住全部三個 SHA-1 哈希值。 而且,你也徹底不知道是誰保存了這些快照,在什麼時刻保 存的,以及爲何保存這些快照。而以上這些,正是提交對象(commit object) 能爲你保存的基本信息

提交對象

咱們能夠經過調用 commit-tree 命令建立一個提交對象,爲此須要指定一個樹 對象的 SHA-1 值,以及該提交的父提交對象(若是有的話 第一次將暫存區作快 照就沒有父對象)

建立提交對象:echo 'first commit' | git commit-tree [樹哈希] 返回:fdf4fc3344e67ab068f836878b6c4951e3b15f3d

查看提交對象:git cat-file -p [提交對象哈希]

提交對象的格式很簡單: 它先指定一個頂層樹對象,表明當前項目快照;而後是做者/提交者信息(依 據你的 user.name 和 user.email 配置來設定,外加一個時間戳);留空 一行,最後是提交註釋

提交對象視圖

Git 操做命令集

建立工做目錄 對工做目錄進行修改

  1. git add ./ 將目錄下全部文件進行如下操做(存入項目對象,在存入暫存區) git hash-object -w 文件名 (修改了多少個文件目錄中的文件,次命令就要被執行多少次) git ipdata-index .... (存入暫存區)
  2. git commit -m "註釋內容" 暫存區存入數據庫,並對應建立樹對象,提交對象 git write-tree 建立樹對象 git commit-tree 提交對象

存文件:git hash-object -w 文件路徑 返回文件對應鍵值:git hash-object 文件路徑 根據鍵值拉取數據:git cat-file -p [filehash]

查看暫存區:git ls-files -s 查看樹對象:git cat-file -p master^{tree}(或者是樹對象的 hash) 暫存區生成樹對象存入庫:git write-tree

初始化倉庫:git init 檢查當前文件狀態:git status

將修改添加到暫存區: git add ./ 查看哪些更新尚未暫存:git diff(不加參數直接輸入 git diff) 查看哪些更新已暫存準備下次提交:git diff –cached 或者 git diff –staged(1.6.1 以上) 檢查當前文件狀態:git status

將暫存區提交到版本庫: git commit -m 註釋 跳過暫存區直接提交到版本庫:git commit -a 跳過暫存區直接提交到版本庫並寫註釋:git commit -a -m 註釋

刪除文件:git rm 文件名 刪除工做目錄對應的文件,在將修改添加到暫存區 清空暫存:rm .git/index 刪除暫存區的全部文件 文件更名:git mv 文件名 新文件名 將工做目錄的文件名進行修改,在將修改添加到暫存區

查看歷史記錄: git log 查看全部分支的全部操做記錄:git reflog

退回版本並建立、切換該分支:首先git reflog找到舊版本hash值,在調用git branch -b 分支名 提交對象hash 直接退回舊版本:git reset [分支hash]:將HEADIndexWorking直接跳到所對應分支上

分支操做

建立分支: git branch branchname 切換分支:git checkout branchname 建立&切換分支:git checkout -b branchname 建立&指定提交對象:git branch branchname 提交對象hash 版本穿梭(時光機): git branch branchname commitHash 普通刪除分支:git branch -d branchname 強制刪除分支: git branch -D branchname 合併分支:git merge branchname 快進合併 --> 不會產生衝突 典型合併 --> 有機會產生衝突 解決衝突 --> 打開衝突的文件 進行修改 add commit

查看分支列表: git branch 查看合併到當前分支的分支列表: git branch --merged 一旦出如今這個列表中 就應該刪除 查看沒有合併到當前分支的分支列表:git branch --no-merged 一旦出如今這個列表中 就應該觀察一下是否須要合併

儲存操做

在分支上的工做作到一半時 若是有切換分支的需求, 咱們應該將現有的工做存儲起來 將當前分支上的工做推到一個棧中:git stash 分支切換 進行其餘工做 完成其餘工做後 切回原分支 將棧頂的工做內容還原:git stash apply || git stash apply stash@{2} 刪除棧:git stash drop git stash apply + git stash drop: git stash pop 查看存儲:git stash list

遠程協助

推送本地項目到遠程倉庫:git push [遠程倉庫別名] [分支名] 克隆遠程倉庫到本地:git clone [遠程倉庫url] 拉取遠程倉庫更新:git fetch [remote-name] [更新到遠程跟蹤分支] 推送本地分支&建立遠程分支:git push origin [本地分支名]

在新建分支後,能夠指定想要跟蹤的遠程分支 git checkout -b 本地分支名 遠程跟蹤分支名 若是已經拉取數據(git fatch [remote-name]),能夠直接指定遠程分支名建立本地分支名,並跟蹤遠程分支。 git checkout --track 遠程跟蹤分支名 將當前分支跟蹤一個剛剛拉取下來的遠程分支 git branch -u origin/serverfix (--set-upstream-to) 查看分支是否有跟蹤遠程分支綁定 git branch -vv

刪除遠程分支:git push origin --delete serverfix 列出仍在遠程跟蹤可是遠程已被刪除的無用分支:git remote prune origin --dry-run 清除上面命令列出來的遠程跟蹤:git remote prune origin

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.lifs "ls-files -s"
[分叉歷史] $ git config --global alias.brlog "log --oneline --decorate --graph --all"

Git 高層命令(CRUD)

初始化倉庫:git init(初始化)

做用:初始化後,在當前目錄下會出現一個名爲 .git 的目錄,全部 Git 須要 的數據和資源都存放在這個目錄中。不過目前,僅僅是按照既有的結構框架初始化 好了裏邊全部的文件和目錄,但咱們尚未開始跟蹤管理項目中的任何一個文件。

工做目錄下面的全部文件都不外乎這兩種狀態:已跟蹤未跟蹤

已跟蹤的文件是指原本就被歸入版本控制管理的文件,在上次快照中有它 們的記錄,工做一段時間後,它們的狀態多是已提交已修改或者已暫存

全部其餘文件都屬於未跟蹤文件。它們既沒有上次更新時的快照,也不在 當前的暫存區域。

初次克隆某個倉庫時,工做目錄中的全部文件都屬於已跟蹤文件,且狀態 爲已提交;在編輯過某些文件以後,Git 將這些文件標爲已修改。咱們逐步把 這些修改過的文件放到暫存區域,直到最後一次性提交全部這些暫存起來的文 件。使用 Git 時的文件狀態變化週期以下圖所示

檢查當前文件狀態:git status

肯定文件當前處於什麼狀態

若是建立一個新文件 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)

跟蹤新文件:git add(暫存)

做用:跟蹤一個新文件

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

Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README

只要在 「Changes to be committed」 這行下面的,就說明是已暫存狀態。

若是此時提交,那麼該文件此時此刻的版本將被留存在歷史記錄中。在 git add 後面能夠指明要跟蹤的文件目錄路徑若是是目錄的話,就說明要遞歸 跟蹤該目錄下的全部文件。(譯註:其實 git add 的潛臺詞就是把目標文件快 照放入暫存區域,也就是 add file into staged area,同時不曾跟蹤過的文件標 記爲已跟蹤。)

如今 README 文件都已暫存,下次提交時就會一併記錄到倉庫。假設此時, 你想要在 README 裏再加條註釋,從新編輯存盤後,準備好提交。不過且慢,再 運行 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)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README

README 文件出現了兩次!一次算已修改,一次算已暫存,這怎麼可能呢? 好吧,實際上 Git 只不過暫存了你運行 git add 命令時的版本,若是如今提交,那 麼提交的是添加註釋前的版本,而非當前工做目錄中的版本。因此,運行了 git add 以後又做了修訂的文件,須要從新運行 git add 把最新版本從新暫存起來

$ git add README
$ git status

git diff 命令.這個命令它已經能解決咱們 兩個問題了:當前作的哪些更新尚未暫存?有哪些更新已經暫存起來準備 好了下次提交?

查看哪些更新尚未暫存

命令:git diff(不加參數直接輸入 git diff)

查看哪些更新已暫存準備下次提交

命令: git diff –cached 或者 git diff –staged(1.6.1 以上)

提交更新:git commit(提交)

當暫存區域已經準備穩當能夠提交時,在此以前,請必定要確認還有什麼修改 過的或新建的文件尚未 git add 過,不然提交的時候不會記錄這些還沒暫存起來 的變化。因此,每次準備提交前,先用 git status 看下,是否是都已暫存起來了, 而後再運行提交命令 git commit

git commit會啓動文本編輯器以便輸入本次提交的說明 默認的提交消息包含最後一次運行 git status 的輸出,放在註釋行裏, 另外開頭還有一空行,供你輸入提交說明。你徹底能夠去掉這些註釋行, 不過留着也不要緊,多少能幫你回想起此次更新的內容有哪些。

以用 -m 參數後跟提交說明的方式,在一行命令中提交更新:git commit –m 「message xxx」

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

跳過使用暫存區域

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

移除文件: git rm 文件名(刪除)

要從 Git 中移除某個文件,就必需要從已跟蹤文件清單中註冊刪除(確切地說, 是在暫存區域註冊刪除),而後提交。能夠用 git rm 命令完成此項工做,並連帶 從工做目錄中刪除指定的文件,這樣之後就不會出如今未跟蹤文件清單中了。

[注意] 刪除並非真正意義上的刪除,rm命令運行後要進行git add ./ 以及git commit -m 我刪除了,刪除操做實際上只是刪除了工做空間的文件 ,而且在數據庫裏面會存着刪除的信息

文件更名:git mv 文件名(更名)

git mv laoliu.txt laoliuliu.txt git commit -a / git status

$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed:    laoliu.txt -> laoliuliu.txt

其實,運行 git mv 就至關於運行了下面三條命令:

$ mv laoliu.txt laoliuliu.txt
$ git rm laoliu.txt
$ git add laoliuliu.txt

查看歷史記錄: git log(提交)

在提交了若干更新,又或者克隆了某個項目以後,你也許想回顧下提交歷史。 完成這個任務最簡單而又有效的工具是 git log 命令

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

只顯示一行:git log --pretty=oneline 顯示一行並截取hash值:git log --oneline

Git 分支(殺手功能)

幾乎全部的版本控制系統都以某種形式支持分支。 使用分支意味着你能夠把你的工做從開發主線上分離開來,以避免影響開發主線。 在不少版本控制系統中,這是一個略微低效的過程——經常須要徹底建立一個源代碼目錄的副本。對於大項目來講,這樣的過程會耗費不少時間。

Git 的分支模型極其的高效輕量的。是 Git 的必殺技特性,也正由於這一特性,使 得 Git 從衆多版本控制系統中脫穎而出

爲你建立了一個能夠移動的新的指針。 好比,建立一個 testing 分 支:git branch testing。這會在當前所在的提交對象上建立一個指針

建立分支

建立&切換分支

建立分支

git branch 分支名 分支名 建立 一個新分支,並不會自動切換到新分支中去

新建且使分支指向提交對象**

git branch 分支名 提交對象hash

切換分支

git checkout 分支名 切回主分支:git checkout master

分支切換會改變你工做目錄中的文件,在切換分支時,必定要注意你工做目錄裏的文件會被改變。 若是是切換 到一個較舊的分支,你的工做目錄會恢復到該分支最後一次提交時的樣子。如 果 Git 不能幹淨利落地完成這個任務,它將禁止切換分支

切換分支會動三個地方:HEAD、暫存區、工做目錄

注意要點:每次切換分支前 當前分支必定得是乾淨的(已提交狀態),以及在切換分支時 若是當前分支上有未暫存的修改(第一次) 或者 有未提交的暫存(第一次)分支能夠切換成功 可是這種操做可能會污染其餘分支

新建分支並切換分支

git checkout -b 分支名

查看分支

git branch 不僅是能夠建立與刪除分支。 若是不加任何參數運行它, 會獲得當前全部分支的一個列表

查看每一個分支最後一次提交

git branch -v

查看哪些分支已經合併到當前分支

git branch –merged 查看哪些分支已經合併到當前分支,在這個列表中分支名字前沒有 * 號的分支一般可使用 git branch -d 刪除掉;

查看全部包含未合併工做的分支

git branch --no-merged 查看全部包含未合併工做的分支 嘗試使用 git branch -d 命令刪除在這個列表中的分支時會失敗。 若是真的想要刪除分支並丟掉那些工做,可使用 -D 選項強制刪 除它。

查看項目分叉歷史

git log --oneline --decorate --graph --all

刪除分支

git branch -d 分支名

分支合併

git merge 分支名

快進fast-forward

在合併的時候,有時候會出現"快進(fast-forward)"這個詞。 因爲當 前 master 分支所指向的提交是你當前提交的直接上游,因此 Git 只是簡 單的將指針向前移動。 換句話說,當你試圖合併兩個分支時,若是順着一個 分支走下去可以到達另外一個分支,那麼 Git 在合併二者的時候,只會簡單的 將指針向前推動(指針右移),由於這種狀況下的合併操做沒有須要解決的分 歧——這就叫作 「快進(fast-forward

產生文件衝突

有時候合併操做不會如此順利。 若是你在兩個不一樣的分支中,對同一個 文件的同一個部分進行了不一樣的修改,Git 就無法乾淨的合併它們。 若是你 對 #53 問題的修改和有關 hotfix 的修改都涉及到同一個文件的同一 處,在合併它們的時候就會產生合併衝突

此時 Git 作了合併,可是沒有自動地建立一個新的合併提交。 Git 會暫 停下來,等待你去解決合併產生的衝突。 你能夠在合併衝突後的任意時刻 使用 git status 命令來查看那些因包含合併衝突而處於未合併(unmerged) 狀態的文件

任何因包含合併衝突而有待解決的文件,都會以未合併狀態標識出來。

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

在你解決了全部文件裏的衝突以後,對每一個文件使用 git add 命令來將其 標記爲衝突已解決。 一旦暫存這些本來有衝突的文件,Git 就會將它們標記 爲衝突已解決

分支流程

建立分支

建立分支

修改分支並提交

修改分支

切回主分支

切回分支

分支實際案例

工做流

  1. 開發某個網站。
  2. 爲實現某個新的需求,建立一個分支。
  3. 在這個分支上開展工做。

緊急任務

正在此時,你忽然接到一個電話說有個很嚴重的問題須要緊急修補。 你 將按照以下方式來處理:

  1. 切換到你的線上分支(production branch)。
  2. 爲這個緊急任務新建一個分支,並在其中修復它。
  3. 在測試經過以後,切換回線上分支,而後合併這個修補分支,最後將改 動推送到線上分支。
  4. 切換回你最初工做的分支上,繼續工做。

詳細流程

首先,咱們假設你正在你的項目上工做,而且已經有一些提交

正常工做

如今,你已經決定要解決你的公司使用的問題追蹤系統中的 #53 問題。 想要 新建一個分支並同時切換到那個分支上,你能夠運行一個帶有 -b 參數的 git checkout 命令 git checkout -b iss53 至關於git branch iss53 && git checkout iss53

建立分支解決問題

你繼續在 #53 問題上工做,而且作了一些提交。 在此過程當中,iss53 分 支在不斷的向前推動,由於你已經檢出到該分支

分支提交

!!!如今你接到那個電話,有個緊急問題等待你來解決

有了 Git 的幫助,你沒必要把這個緊急問題和 iss53 的修改混在一 起,你也不須要花大力氣來還原關於 53# 問題的修改,而後再添加關於這個 緊急問題的修改,最後將這個修改提交到線上分支。 你所要作的僅僅是切換 回 master 分支 可是,在你這麼作以前,要留意你的工做目錄和暫存區裏那些尚未 被提交的修改,它可能會和你即將檢出的分支產生衝突從而阻止 Git 切換到 該分支。 最好的方法是,在你切換分支以前,保持好一個乾淨的狀態。git checkout master(提 交你的全部修改)

這個時候,你的工做目錄和你在開始 #53 問題以前如出一轍,如今你可 以專心修復緊急問題了。 請牢記:當你切換分支的時候,Git 會重置你的工 做目錄,使其看起來像回到了你在那個分支上最後一次提交的樣子。 Git 會 自動添加、刪除、修改文件以確保此時你的工做目錄和這個分支最後一次提交 時的樣子如出一轍。

!!!接下來,你要修復這個緊急問題。 讓咱們創建一個針對該緊急問 題的分支(hotfix branch),在該分支上工做直到問題解決

git checkout -b hotfix問題解決後:git commit -a -m 'fixed the broken email address'

問題解決提交

!!!你能夠運行你的測試,確保你的修改是正確的,而後將其合併回你 的 master 分支來部署到線上。 你可使用 git merge 命令來達到上 述目的

git checkout master git merge hotfix

在合併的時候,有時候會出現"快進(fast-forward)"這個詞。 因爲當 前 master 分支所指向的提交是你當前提交的直接上游,因此 Git 只是簡 單的將指針向前移動。 換句話說,當你試圖合併兩個分支時,若是順着一個 分支走下去可以到達另外一個分支,那麼 Git 在合併二者的時候,只會簡單的 將指針向前推動(指針右移),由於這種狀況下的合併操做沒有須要解決的分 歧——這就叫作 「快進(fast-forward

問題解決合併分支

!!!關於這個緊急問題的解決方案發布以後,你準備回到被打斷以前時 的工做中。 然而,你應該先刪除 hotfix 分支,由於你已經再也不須要它了 —— master 分支已經指向了同一個位置。 你可使用帶 -d 選項的 git branch 命令來刪除分支。如今你能夠切換回你正在工做的分支繼續你的工 做,也就是針對 #53 問題的那個分支

git branch -d hotfix git checkout iss53

回到分支

你在 hotfix 分支上所作的工做並無包含到 iss53 分支中。 若是你需 要拉取 hotfix 所作的修改,你可使用 git merge master 命令 將 master 分支合併入 iss53 分支,或者你也能夠等到 iss53 分支完成其 使命,再將其合併回 master 分支。 git checkout master git merge iss53

當前的合併和你以前合併 hotfix 分支的時候看起來有一點不同。 在 這種狀況下,你的開發歷史從一個更早的地方開始分叉開來(diverged)。 因 爲,master 分支所在提交併非 iss53 分支所在提交的直接祖先,Git 不 得不作一些額外的工做。 出現這種狀況的時候,Git 會使用兩個分支的末端 所指的快照(C4 和 C5)以及這兩個分支的工做祖先(C2),作一個簡單 的三方合併。

子分支合併主分支

和以前將分支指針向前推動所不一樣的是,Git 將這次三方合併的結果作了一個新的 快照而且自動建立一個新的提交指向它。 這個被稱做一次合併提交,它的特別之處在 於他有不止一個父提交。

子分支合併主分支2

須要指出的是,Git 會自行決定選取哪個提交做爲最優的 共同祖先,並以此做爲合併的基礎;這和更加古老的 CVS 系 統或者 Subversion (1.5 版本以前)不一樣,在這些古老的版本 管理系統中,用戶須要本身選擇最佳的合併基礎。 Git 的這個 優點使其在合併操做上比其餘系統要簡單不少

最終刪除 iss53 號分支:git branch -d iss53

衝突:有時候合併操做不會如此順利。 若是你在兩個不一樣的分支中,對同一個 文件的同一個部分進行了不一樣的修改,Git 就無法乾淨的合併它們。 若是你 對 #53 問題的修改和有關 hotfix 的修改都涉及到同一個文件的同一 處,在合併它們的時候就會產生合併衝突

此時 Git 作了合併,可是沒有自動地建立一個新的合併提交。 Git 會暫 停下來,等待你去解決合併產生的衝突。 你能夠在合併衝突後的任意時刻 使用 git status 命令來查看那些因包含合併衝突而處於未合併(unmerged) 狀態的文件

任何因包含合併衝突而有待解決的文件,都會以未合併狀態標識出來。

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

在你解決了全部文件裏的衝突以後,對每一個文件使用 git add 命令來將其 標記爲衝突已解決。 一旦暫存這些本來有衝突的文件,Git 就會將它們標記 爲衝突已解決

長期分支

許多使用 Git 的開發者都喜歡使用這種方式來工做,好比只在 master 分支上保留完 全穩定的代碼——有可能僅僅是已經發布或即將發佈的代碼。 他們還有一些名 爲 develop 或者 next 的平行分支,被用來作後續開發或者測試穩定性——這些分支 沒必要保持絕對穩定,可是一旦達到穩定狀態,它們就能夠被合併入 master 分支了。, 等待下一次的發佈。

公司常見模式

隨着你的提交而不斷右移的指針。穩定分支的指針老是在提交歷史中落後一大截, 而前沿分支的指針每每比較靠前。

分支右移

特性分支

特性分支對任何規模的項目都適用。 特性分支是一種短時間分支,它被用來 實現單一特性或其相關工做。 也許你歷來沒有在其餘的版本控制系統(VCS) 上這麼作過,由於在那些版本控制系統中建立和合並分支一般很費勁。 然而, 在 Git 中一天以內屢次建立、使用、合併、刪除分支都很常見。

實例: 考慮這樣一個例子,你在 master 分支上工做到 C1,這時爲了解 決一個問題而新建 iss91 分支,在 iss91 分支上工做到 C2,這時思路 斷了,你暫時放棄修復 iss91,切回主分支又工做到了 c3(畫了幾個頁面)。 這時你忽然對 iss91 問題有了新的想法,你切回 iss91 繼續工做到了 c6。 在完成了對 iss91 的 bug 修復以後。你發現你 C4 以後的修改都沒有使用 ES6 語法。因而你再新建一個 iss91v2 分支從新使用 ES6 語法開發到 C8,寫 了一會寫累了。接着你回到 master 分支又畫了一會頁面到 C10,畫完頁面 後你一咬牙切回 iss91v2 完成 es6 版本的修改到 C11. 你又冒出了一個不 太肯定的想法,切回 master 後新建一個 dumbidea 分支,並在上面作些實 驗。 你的提交歷史看起來像下面這個樣子:

提交歷史

如今,咱們假設兩件事情:你決定使用第二個方案來解決那個問題,即便 用在 iss91v2 分支中方案;另外,你將 dumbidea 分支拿給你的同事看 過以後,結果發現這是個驚人之舉。 這時你能夠拋棄 iss91 分支(即丟 棄 C5 和 C6 提交),而後把另外兩個分支合併入主幹分支。 最終你的提交 歷史看起來像下面這個樣子:

在 master 分支是先合併 dumbidea 分支
切回 iss91v2 分支合併掉 iss91
刪除 iss91
切回 master 分支再合併 iss91v2 分支

提交歷史2

分支本質

Git 的分支,其實本質上僅僅是指向提交對象的可變指針。 Git 的默認分支 名字是 master。 在屢次提交操做以後,你其實已經有一個指向最後那個提交對 象的 master 分支。 它會在每次的提交操做中自動向前移動。

注意 :Git 的 「master」 分支並非一個特殊分支。 它就跟其它分支徹底沒有區別。 之所 以幾乎每個倉庫都有 master 分支,是由於 git init 命令默認建立它,而且大多數 人都懶得去改動它。

master

分支原理

.git/refs 目錄

這個目錄中保存了分支及其對應的提交對象

HEAD 引用

當運行相似於 git branch (branchname) 這樣的命令時,Git 會取得當前所在分支最新提交對應的 SHA-1 值,並將其加入你想要建立的 任何新分支中。

當你執行 git branch (branchname) 時,Git 如何知道最新提 交的 SHA-1 值呢? 答案是 HEAD 文件。

HEAD 文件是一個符號引用(symbolic reference),指向目前所在的分 支。 所謂符號引用,意味着它並不像普通引用那樣包含一個 SHA-1 值。 它是一個指向其餘引用的指針

Git 儲存

有時,當你在項目的一部分上已經工做一段時間後,全部東西都進入了混亂的狀 態,而這時你想要切換到另外一個分支作一點別的事情。 問題是,你不想僅僅由於 過會兒回到這一點而爲作了一半的工做建立一次提交。 針對這個問題的答案是git stash 命令

建立儲存

命令會將未完成的修改保存到一個棧上,而你 能夠在任什麼時候候從新應用這些改動(git stash apply)

查看存儲

git stash list git stash apply stash@{2}

若是不指定一個儲藏,Git 認爲指定的是最近的儲藏

應用儲藏並從棧上清除

git stash pop

移除儲藏

git stash drop

Git 後悔藥

工做目錄文件撤銷

命令:git checkout -- 文件名 做用:將在工做目錄中對文件的修改撤銷

暫存區文件撤銷

命令:git reset HEAD 文件名 做用:將文件從暫存區中撤回到工做目錄

覆蓋提交

命令:git commit --amend

做用:這個命令會將暫存區中的文件提交,並將上一次提交覆蓋

若是你提交後發現忘記了暫存某些須要的修改,能夠像下面這樣操做 git commit -m 'initial commit' --->[提交了但發現還有東西要修改] git add forgotten_file ---> [修改後添加入暫存] git commit –amend ---> [覆蓋以前的提交] 最終你只會有一個提交 - 第二次提交將代替第一次提交的結果

Git 移動指針(reset)

細化基本流程

當咱們運行 git init,這會建立一個 Git 倉庫,其中的 HEAD 引用指向未建立的分支。此時,只有工做目錄有內容

init

如今咱們想要提交這個文件,因此用 git add 來獲取工做目錄中的內容, 並將其複製到索引中

add

接着運行 git commit,它會取得索引中的內容並將它保存爲一個永久的快 照,而後建立一個指向該快照的提交對象,最後更新 master 來指向本次提交

commit

此時若是咱們運行 git status,會發現沒有任何改動,由於如今三棵樹完 全相同

如今咱們想要對文件進行修改而後提交它。 咱們將會經歷一樣的過程;首先在 工做目錄中修改文件。 咱們稱其爲該文件的 v2 版本,並將它標記爲紅色

editFile

若是如今運行 git status,咱們會看到文件顯示在 「Changes not staged for commit,」 下面並被標記爲紅色,由於該條目在索引與工做目錄之間存在不一樣。 接着咱們運行 git add 來將它暫存到索引中

addv2

此時,因爲索引和 HEAD 不一樣,若運行 git status 的話就會看到 「Changes to be committed」 下的該文件變爲綠色 ——也就是說,如今預期的下 一次提交與上一次提交不一樣。 最後,咱們運行 git commit 來完成提交。

commitv2

如今運行 git status 會沒有輸出,由於三棵樹又變得相同了

切換分支或克隆的過程也相似。 當檢出一個分支時,它會修改 HEAD 指向新的分支引用,將 索引 填充爲該次提交的快照,而後將 索引 的內容複製 到 工做目錄 中。

reset 回退三部曲

reset 作的第一件事是移動 HEAD 的指向,假設咱們再次修改了 file.txt 文件並第三次提交它。 如今的歷史看 起來是這樣

commitv3

回退提交

git reset –soft HEAD~,回退指針。這與改變 HEAD 自身不一樣(checkout 所作的);reset 移動 HEAD 指向的分支。

reset

看一眼上圖,理解一下發生的事情:它本質上是撤銷了上一次 git commit 命令。 當你在運行 git commit 時,Git 會建立一個新的提交,並 移動 HEAD 所指向的分支來使其指向該提交。

當你將它 reset 回 HEAD~(HEAD 的父結點)時,其實就是把該分支移 動回原來的位置,而不會改變索引和工做目錄。 如今你能夠更新索引並再次運 行 git commit 來完成 git commit --amend 所要作的事情了。

回退暫存區(索引)

resetv2

注意: git reset HEAD~ 等同於 git reset –mixed HEAD~

理解一下發生的事情:它依然會撤銷一上次 提交,但還會 取消暫存 全部 的東西。 因而,咱們回滾到了全部 git add 和 git commit 的命令執行以前。

回退工做目錄

resetv3

git reset --hard HEAD~:你撤銷了最後的提交、git add 和 git commit 命令以及工做目錄 中的全部工做。

必須注意:--hard 標記是 reset 命令惟一的危險用法,它也是 Git 會 真正地銷燬數據的僅有的幾個操做之一。 其餘任何形式的 reset 調用均可 以輕鬆撤消,可是 --hard 選項不能,由於它強制覆蓋了工做目錄中的文件。 在這種特殊狀況下,咱們的 Git 數據庫中的一個提交內還留有該文件的 v3 版 本,咱們能夠經過 reflog 來找回它。可是若該文件還未提交,Git 仍會覆 蓋它從而致使沒法恢復。

reset 文件路徑

reset 還能夠給它提供一個做用路徑。 若 指定了一個路徑,reset 將會跳過第 1 步,而且將它的做用範圍限定爲指定的文 件或文件集合。

resetfile

如今,假如咱們運行 git reset file.txt (這實際上是 git reset --mixed HEAD file.txt 的簡寫形式,),它會: 移動 HEAD 分支的指向 (由於是文件這一步忽略) 將 file.txt 從 HEAD 複製到索引中

resetfilev2

reset [bran-hash](指定指針)

git reset [分支hash]:將HEADIndexWorking直接跳到所對應分支上

checkout [bran-hash](指定指針)

運行 git checkout [branch] 與運行 git reset [branch] 很是類似,它會更新三者使其看起來像 [branch],不過有兩 點重要的區別

首先不一樣於 reset --hard,checkout 對工做目錄是安全的,它會 經過檢查來確保不會將已更改的文件弄丟。而 reset --hard 則會不作檢 查就全面地替換全部東西。

第二個重要的區別是如何更新 HEAD。 reset 會移動 HEAD 分支的 指向,而 checkout 只會移動 HEAD 自身來指向另外一個分支。

退回v2版本並建立、切換該分支

$ git branch -b 分支名 提交對象hash

Git 標籤(版本號)

打 tag:Git 能夠給歷史中的某一個提交打上標籤,以示重要。 比較有表明性的是人們會 使用這個功能來標記發佈結點(v1.0 等等)。

列出標籤

git tag

建立標籤

當前分支建立

git tag 1.0

指定分支建立

git tag v1.4 commitHash

建立附註標籤

[打開文本編輯器添加註釋]git tag -a v1.4 [能夠指定分支]git tag -a v1.4 commitHash [能夠單行註釋]git tag -a v1.4 commitHash -m 'my version 1.4'

查看標籤

git show 能夠顯示任意類型的對象(git 對象 樹對象 提交對象 tag 對象)

git show tagname

遠程標籤

默認狀況下,git push 命令並不會傳送標籤到遠程倉庫服務器上。 在建立完 標籤後你必須顯式地推送標籤到 共享服務器上。你能夠運行 git push origin [tagname]

刪除標籤

刪除標籤 要刪除掉你本地倉庫上的標籤,可使用命令 git tag -d 。 例如,可使用下面的命令刪除掉 一個輕量級標籤 git tag -d v1.4

注意:上述命令並不會從任何遠程倉庫中移除這個標籤,你必須使用 git push :refs/tags/ 來更新你的遠程倉庫 git push origin :refs/tags/v1.4

檢出標籤分支

若是你想查看某個標籤所指向的文件版本,可使用 git checkout 命令 git checkout tagname

雖說這會使你的倉庫處於「分離 頭指針(detacthed HEAD)」狀態。在「分 離頭指針」狀態下,若是你作了某些更改而後提交它們,標籤不會發生變化,但你 的新提交將不屬於任何 分支,而且將沒法訪問,除非訪問確切的提交哈希。所以, 若是你須要進行更改——好比說你正在修復舊版本的錯 誤——這一般須要建立一 個新分支: git checkout -b version2

Git 統一代碼風格

Git 中結合 Eslint。讓代碼在沒有經過 Eslint 的狀況下 禁止提交。 pre-commit 、哈士奇、eslintignore

EditorConfig

在團隊開發中,統一的代碼格式是必要的。可是不一樣開發人員使用的編輯工具可能 不一樣,這樣就形成代碼的不統一。

目前爲止,仍是有不少人陷入在 tabs vs spaces 之類的爭論中。不是每一個人都在嚴 格要求本身的代碼規範和風格,對於多人協做的項目這容易出現問題。畢竟每一個人所用 的 IDE 和編輯器均可能不一樣。

EditorConfig 幫助開發人員定義和維護不一樣編輯器之間一致的編碼風格。 EditorConfig 項目由定義編碼樣式的文件格式和一組文本編輯器插件組成,這些插件使 編輯器可以讀取文件格式並堅持已定義的樣式。編輯器配置文件易於閱讀,而且能夠很 好地與版本控制系統一塊兒工做。

你只需配置一個 .editorconfig 文件,在其中設置好要遵照的代碼規範,放在項目 的根目錄下,就可以在幾乎全部的主流 IDE 和編輯器中複用了,能夠將 .editorconfig 文件也提交到版本控制系統中,就不須要針對不一樣 IDE 和編輯器再單獨進行設置了。

配置文件

EditorConfig 插件會自動在項目中尋找名爲 .editorconfig 的配置文 件,每一個文件的樣式偏好會自動根據該文件所在文件夾的 .editorconfig 文 件向上尋找全部同名文件,直到某個配置的文件種包含了 root=true。最接 近該文件的配置文件中的設置優先最高

具體流程

1. 初始化倉庫

git init

2. 安裝eslint

建立項目:npm init 本地安裝:npm i eslint --save-dev 設置啓動命令(package.json)

"scripts": { "lint": "eslint src", "lint:create": "eslint --init" }

[自定義命令名]eslint src[校驗目錄代碼] [自定義命令名]:eslint init[生成配置文件]

3. 運行eslint初始化

npm run lint:create

4. 安裝Husky

npm install husky --save-dev

5. 配置package.json

// package.json
"husky": {
"hooks": {
// 提交前,執行npm run link 否則不能提交
"pre-commit": "npm run link",
"pre-push": "npm test",
}
}

6 . 忽略module文件

在Git根倉庫建立.gitignore文件,寫入

/node_modules

7. Git進行提交

git commit -m "commit v1"

這時候,提交時若是檢測到js語法的錯誤,那麼提交將會被阻止

忽略某些文件

總會有些文件無需歸入 Git 的管理,也不但願它們總出如今未跟蹤 文件列表。一般都是些自動生成的文件,好比日誌文件,或者編譯過程當中建立的臨 時文件等。咱們能夠建立一個名爲 .gitignore 的文件,列出要忽略的文件模式。

*.[oa]
*~

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

gitignore 的格式規範

全部空行或者以註釋符號 # 開頭的行都會被 Git 忽略。可使用標準的 glob 模式匹配。

/* 表明匹配任意個字符
?表明匹配任意一個字符
** 表明匹配多級目錄
匹配模式前跟反斜槓(/) 這個斜槓表明項目根目錄
匹配模式最後跟反斜槓(/)說明要忽略的是目錄。
要忽略指定模式之外的文件或目錄,能夠在模式前加上驚歎號(!)取反。

示例

# 此爲註釋 – 將被 Git 忽略

忽略全部 .a 結尾的文件

*.a

但 lib.a 除外

!lib.a

僅僅忽略項目根目錄下的 TODO 文件,不包括 subdir/TODO

/TODO

忽略 全部build/ 目錄下的全部文件

build/

會忽略 doc/notes.txt 但不包括 doc/server/arch.txt

doc/*.txt

忽略 doc/ 目錄下全部擴展名爲 txt 的文件

doc/**/*.txt #(**通配符從 Git 版本 1.8.2 以上已經可使用)

.gitignore 文件列 表

https://github.com/github/gitignore

遠程倉庫

HTTPS遠程提交

1. 配置本地倉庫

git init.......

配置倉庫用戶信息

用戶名稱:git config user.name "[name]" 用戶郵箱:git config user.email [email] 檢查已有的配置信息:git config --list 刪除配置信息: git config --unset user.email

git add ./......git commit......

2. 配置遠程倉庫別名

git remote add <shortname> <url>

顯示遠程倉庫使用的 Git 別名與其對應的 URL git remote –v 查看更多信息 git remote show [remote-name] 重命名 git remote rename pb paul

3. 推送本地項目到遠程倉庫

git push [遠程倉庫別名] [分支名]

SSH遠程提交

1. 粘貼如下文本,替換爲您的GitHub電子郵件地址。

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

使用提供的電子郵件做爲標籤,這將建立一個新的ssh密鑰。

> Generating public/private rsa key pair.

2. 當提示您「輸入要在其中保存密鑰的文件」時,請按Enter。這接受默認文件位置。

> Enter a file in which to save the key (/c/Users/you/.ssh/id_rsa):[Press enter]

3. 在提示符下,鍵入一個安全密碼。有關更多信息,請參閱「使用SSH密鑰密碼短語」

> Enter passphrase (empty for no passphrase): [Type a passphrase] > Enter same passphrase again: [Type passphrase again]

4. 打開C:/Users/Administrator/.ssh/id_rsa.pub,將其添加到GitHub的SSH密匙中

add-ssh

Git綁定鏈接:$ ssh -T git@github.com

// 沒法肯定主機真實性,密匙爲......,是否繼續鏈接
The authenticity of host 'github.com (13.229.188.59)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

輸入安全密碼

Warning: Permanently added 'github.com,13.229.188.59' (RSA) to the list of known hosts.
Enter passphrase for key '/c/Users/Administrator/.ssh/id_rsa':[Type a passphrase]

1. 配置本地倉庫

git init.......

配置倉庫用戶信息

用戶名稱:git config user.name "[name]" 用戶郵箱:git config user.email [email] 檢查已有的配置信息:git config --list 刪除配置信息: git config --unset user.email

git add ./......git commit......

2. 配置遠程倉庫別名

git remote add <shortname> <url> ssh-url

顯示遠程倉庫使用的 Git 別名與其對應的 URL git remote –v 查看更多信息 git remote show [remote-name] 重命名 git remote rename pb paul

3. 推送本地項目到遠程倉庫

git push [遠程倉庫別名] [分支名]

HTTPS&SHH

若是我想要給別人的倉庫提交代碼

  • 我須要把我本機的SSH配置到別人帳戶下,而後採用SSH方式提交代碼
  • 把個人帳號添加到那個倉庫的Collaborators,直接使用https方式提交

總結

使用https方式提交的不須要添加SSH,可是使用SSH方式提交的必需要添加本機的SSH A帳戶想要給A帳戶下的倉庫提交代碼,直接使用https方式就行 A帳戶想要給B帳戶下的倉庫提交代碼,1.添加Collaborators使用https方式,或者 2.添加SSH,使用SSH方式提交。

克隆遠程倉庫到本地

git clone [遠程倉庫url](克隆時不須要 git init)

git-add-url

默認克隆時爲遠程倉庫起的別名爲 origin。 $ git remote > [origin]

遠程倉庫名字 「origin」 與分支名字 「master」 同樣,在 Git 中並無任何特別 的含義同樣。 同時 「master」 是當你運行 git init 時默認的起始分支名字,緣由僅僅 是它的普遍使用,「origin」 是當你運行 git clone 時默認的遠程倉庫名字。 若是你運 行 git clone -o booyah,那麼你默認的遠程倉庫別名爲 booyah

給予提交的權限

若是你想與他人合做,並想給他們提交的權限,你須要把他們添加爲 「Collaborators」。 若是 Ben,Jeff,Louise 都在 GitHub 上註冊了, 你想給他們推送的權限,你能夠將他們添加到你的項目。 這樣作會給 他們 「推送」 權限,就是說他們對項目有讀寫的權限 點擊邊欄底部的 「Settings」 連接

GitHub項目 >
設置(options) >

管理訪問(Manage access) >
 邀請合做者(Invite a collaborator) >
     指定GitHub用戶名(或郵箱)
        指定用戶接收權限     或    邀請碼連接
            指定用戶就能夠提交了

拉取遠程倉庫更新

git fetch [remote-name]

訪問遠程倉庫,從中拉取全部你尚未的數據。 執行完後,遠程分支就會出現新的內容!! 它並不會自動合併或修改你當前的工做。當準備好時你必須手動將其合併入你的工做。 合併:git merge 遠程分支

git fetch [remote-name]

直接拉取分支數據到當前分支(須要綁定遠程分支)git branch -u origin/serverfix (--set-upstream-to)

git pull

推送其餘分支

想要公開分享一個分支時,須要將其推送到有寫入權限的遠程倉 庫上。 本地的分支並不會自動與遠程倉庫同步 - 你必須顯式地推送想要 分享的分支。 這樣,你就能夠把不肯意分享的內容放到私人分支上,而 將須要和別人協做的內容推送到公開分支。

推送本地的 serverfix 分支,將其做 爲遠程倉庫的 serverfix 分支

git push origin serverfix

下一次其餘協做者從服務器上抓取數據時,他們會在本地生成一個遠程跟蹤分支 origin/serverfix , 指向服務器的 serverfix 分支的引用。

[注意] 當抓取到新的遠 程跟蹤分支時,本地不會自動生成一份可編輯的副本(拷貝)。 換一句話說,這種狀況下,不會有一個新的 serverfix 分支 - 只有一 個不能夠修改的 origin/serverfix 指針。

更換遠程倉庫分支名

git push origin serverfix:awesomebranch

跟蹤遠程分支

本地跟蹤分支

從一個遠程跟蹤分支(origin/master)檢出一個本地分支會 自動建立一個叫作 「跟蹤分支(有時候也叫作 」 「上游分支」 :master)。 只有主分支 而且 克隆時纔會自動建跟蹤分支.

跟蹤分支是與遠程分支有直接關係的本地分支。 若是在一個跟蹤分支上 輸入 git pull,Git 能自動地識別去哪一個服務器上抓取、合併到哪一個 分支。

本地分支跟蹤遠程分支

在新建分支時,能夠指定想要跟蹤的遠程分支 git checkout -b 本地分支名 遠程跟蹤分支名

若是已經拉取數據(git fatch origin),能夠直接指定遠程分支名建立本地分支名,並跟蹤遠程分支。 git checkout --track 遠程跟蹤分支名

將當前分支跟蹤一個剛剛拉取下來的遠程分支 git branch -u origin/serverfix (--set-upstream-to)

查看分支是否有跟蹤遠程分支綁定 git branch -vv

刪除遠程分支

刪除遠程分支:git push origin --delete serverfix

列出仍在遠程跟蹤可是遠程已被刪除的無用分支:git remote prune origin --dry-run

清除上面命令列出來的遠程跟蹤:git remote prune origin

派生

若是你想要參與某個項目,可是並無推送權限,這時能夠對這個項 目進行「派生」(Fork)。 派生的意思是指,GitHub 將在你的空間中創 建一個徹底屬於你的項目副本,且你對其具備推送權限。經過這種方式, 項目的管理者再也不須要忙着把用戶添加到貢獻者列表並給予他們推送權 限。 人們能夠派生這個項目,將修改推送到派生出的項目副本中,並通 過建立合併請求(Pull Request)來讓他們的改動進入源版本庫。

基本流程

1. 從 master 分支中建立一個新分支 (本身 fork 的項目)

  1. 提交一些修改來改進項目 (本身 fork 的項目)
  2. 將這個分支推送到 GitHub 上 (本身 fork 的項目)
  3. 建立一個合併請求
  4. 討論,根據實際狀況繼續修改
  5. 項目的擁有者合併或關閉你的合併請求

git remote add <shortname 源倉庫> <url 源倉庫>
git fetch 遠程倉庫名字
git merge 對應的遠程跟蹤分支

[注意] 每次在發起新的 Pull Request 時 要去拉取最新的源倉庫的代碼 而不是本身 fork 的那個倉庫。

相關文章
相關標籤/搜索