git必知必會

1. Git 配置

--system #系統級別
--global #用戶全局
--local #單獨一個項目

git config --global user.name "xxxx" #用戶名
git config --global user.email "xxxx@xxx.com" #郵箱

git config --list # 列舉全部配置

鏈接遠程倉庫githubgit

  1. 建立SSH Keygithub

    ssh-keygen -t rsa -C <youremail@example.com>
  2. 登錄GitHub,打開Account settings -> SSH Keys -> Add SSH Key,填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容數據庫

  3. 測試是否鏈接緩存

    ssh git@github.com

幾個概念:服務器

工做區(Working Directory): 你在電腦裏能看到的目錄。網絡

暫存區(stage / index): 保存了下次將提交的文件列表信息, 通常存放在 .git目錄下 下的index文件(.git/index)中,因此咱們把暫存區有時也叫做索引(index)app

版本庫(Repository): 工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。ssh

遠程倉庫(Remote)編輯器

忽略文件配置:添加.gitignore文件測試

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

  • 全部空行或者以  開頭的行都會被 Git 忽略。

  • 可使用標準的 glob 模式匹配。

  • 匹配模式能夠以(/)開頭防止遞歸。

  • 匹配模式能夠以(/)結尾指定目錄。

  • 要忽略指定模式之外的文件或目錄,能夠在模式前加上驚歎號(!)取反。

2. 建立版本庫

版本庫又名倉庫,英文名repository,你能夠簡單理解成一個目錄,這個目錄裏面的全部文件均可以被Git管理起來,每一個文件的修改、刪除,Git都能跟蹤,以便任什麼時候刻均可以追蹤歷史,或者在未來某個時刻能夠「還原」。

git clone url # clone遠程倉庫
git init # 初始化本地版本庫

3. Git 分支

master: 默認開發分支

HEAD: 當前開發分支

HEAD^([n])HEAD的第n次父提交提交, ^至關於^1

HEAD~([n])HEAD的第n個祖先提交

origin: 默認遠程版本庫




graph TD;
br1_c1-->master*;
br2_c2-->master*;
br3_c3-->master*;
br1_c1_c1-->br1_c1;
br2_c2_c2-->br2_c2;
br3_c3_c3-->br3_c3;

 

mastermaster分支

*HEAD,當前活躍(開發)分支

br1_c1br1分支的提交第一次提交

br1_c1_c1br1_c1的第一次提交

如何區分`^`和`~`?
據上圖示知,當前開發分支是`master`,即`HEAD`指向`master`, `c1`, `c2`, `c3`是`master`的三次父提交
`HEAD^ -> c1`,`HEAD^2 -> c2`,`HEAD^3 -> c3`, `HEAD~ -> c1`,`HEAD~2 -> c1_c1`
git branch # 查看分支

git branch -r #查看遠程分支

# 此命令將顯示包含特定提交的全部分支。
git branch --contains <commit>

git branch <name> # 建立分支

git checkout <name> # 切換分支

git checkout -b <name> # 建立 + 切換分支

# 重命名本地分支
git branch -m <old-name> <new-name>

# 重命名剛切換的新分支
git branch -m <new-name>

# 重命名遠程分支: 一旦在本地重命名了分支,您須要先遠程刪除該分支,而後再次推送重命名的分支。
git push origin :<old-name>
git push origin <new-name>

git merge <name> # 合併某分支到當前分支

git branch -d <name> # 刪除分支

git branch -D <name> # 強制刪除分支

# 刪除遠程分支(先在本地刪除該分支),原理是把一個空分支push到server上,至關於刪除該分支。
git push origin :<name>

Notecheckout只會移動HEAD指針,reset會改變HEAD的引用值

4. 查看

git status # 查看狀態

git diff <filename> # 查看修改內容

git diff <first_branch>..<second_branch> # 顯示兩次提交之間的差別

git diff --shortstat "@{n day ago}" # 顯示n天的代碼數量

git diff --cached(--staged) # 查看已經暫存起來的變化

git show <commit>:<filename> # 顯示某次提交時,某個文件的內容

git show <commit> # 顯示某次提交的元數據和內容變化

git show --name-only <commit> # 顯示某次提交發生變化的文件

git reflog # 顯示當前分支的最近幾回提交

git blame <filename> # 顯示指定文件修改信息

5. 修改

git add <filename>|<div> # 添加指定文件, 指定目錄(包括子目錄)到暫存區

git add . # 添加當前目錄的全部文件到暫存區

# -p(或-patch)容許交互選擇要提交的每一個跟蹤文件的各個部分。 這樣每一個提交只包含相關的更改。
git add -p

git mv <old-name> <new-name> # 文件更名

git rm --cached <file> # 中止追蹤指定文件,但該文件會保留在工做區

git rm -f <filename> # 強制刪除選項 -f

6. 提交

git commit -m 'message' # 提交版本庫

git commit -a -m 'message' # 添加全部修改文件到暫存區,並提交版本庫(不包括新增文件)

git commit --amend -m # 修改最後一次提交,若是代碼沒有任何新變化,則用來改寫上一次commit的提交信息

Git Commit

7. 撤銷、版本回滾

git reset --hard HEAD # 撤銷工做目錄中暫存的全部未提交文件的修改內容

git reset --keep [commit] # 重置當前HEAD爲指定commit,但保持暫存區和工做區不變

git reset [file] # 重置暫存區的指定文件,與上一次commit保持一致,但工做區不變

git commit --amend # 將暫存區中的文件提交

git checkout [file] # 恢復暫存區的指定文件到工做區

# --patch還可用於選擇性地丟棄每一個被跟蹤文件的部分。
git checkout -p

# 此命令容許您快速切換到先前檢出的分支。 通常說來 - 是前一個分支的別名。 它也能夠與其餘命令一塊兒使用。
git checkout -

# 還原全部本地更改,若是您肯定能夠丟棄全部本地更改,則可使用。
git checkout .

git checkout HEAD <filename> # 取消指定未提交文件的修改內容

git checkout --patch <filename> # 撤消對文件的修改

git revert <commit_id> # 撤銷指定提交

8. 提交歷史

常見參數選項:

-p: 顯示每次提交的內容差別。

—stat: 顯示每次更新的文件修改統計信息。

—shortstat: 只顯示 —stat 中最後的行數修改添加移除統計。

--name-only 僅在提交信息後顯示已修改的文件清單。

--name-status 顯示新增、修改、刪除的文件清單。

--abbrev-commit: 僅顯示 SHA-1 的前幾個字符,而非全部的 40 個字符。

--relative-date: 使用較短的相對時間顯示(好比,2 weeks ago)。

--graph: 顯示 ASCII 圖形表示的分支合併歷史。

—pretty=(oneline,short,medium(默認值),full,fuller,email,raw,format): 這個選項能夠指定使用不一樣於默認格式的方式展現提交歷史。 這個選項有一些內建的子選項供你使用。

- `oneline`: 將每一個提交放在一行顯示,查看的提交數很大時很是有用。
- [`format`](https://git-scm.com/book/zh/v2/Git-基礎-查看提交歷史#rpretty_format): 列出了經常使用的格式佔位符寫法及其表明的意義。

—oneline--pretty=oneline --abbrev-commit 的簡化用法。

--date= (relative|local|default|iso|rfc|short|raw):定製出現日期格式。

常見輸出參數:

-n: 僅顯示最近的 n 條提交

—since—after: 僅顯示指定時間以後的提交

--until—before: 僅顯示指定做者相關的提交。

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

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

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

默認不用任何參數的話,git log 會按提交時間列出全部的更新,最近的更新排在最上面。

git log # 查看全部提交歷史

git log -p -n # 查看最近提交的n條歷史

git log -p -n <filename> # 查看指定文件最近提交的n條歷史

git log alias配置

git log --pretty=format:'%s %C(bold blue)(%an)%Creset' --abbrev-commit

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

# 設置git alias
git config --global alias.slg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
# 顯示每一個提交在過去兩週內引入的差別日誌。
git whatchanged —-since='2 weeks ago'

9. 標籤

Git 能夠給歷史中的某一個提交打上標籤,以示重要。

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

輕量標籤: 很像一個不會改變的分支 - 它只是一個特定提交的引用。它本質上是將提交校驗和存儲到一個文件中 - 沒有保存任何其餘信息。

附註標籤是存儲在 Git 數據庫中的一個完整對象。 它們是能夠被校驗的;其中包含打標籤者的名字、電子郵件地址、日期時間;還有一個標籤信息;而且可使用 GNU Privacy Guard(GPG)簽名與驗證。 一般建議建立附註標籤,這樣你能夠擁有以上全部信息;可是若是你只是想用一個臨時的標籤,或者由於某些緣由不想要保存那些信息,輕量標籤也是可用的。

-a: 建立附註標籤

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

git tag # 列出已有的標籤

git tag <tagname> # 建立標籤,-a 建立附註標籤

git tag -d <tagname> # 刪除掉你本地倉庫上的標籤

git show <tagname> # 查看標籤信息與對應的提交信息

git push origin <tagname> # 推送標籤到遠程倉庫服務器上

git push origin --tags # 一次性推送全部不在遠程倉庫服務器上的標籤

10. 變基

merge: 用來合併一個或者多個分支到你已經檢出的分支中, 而後它將當前分支指針移動到合併結果上,現有分支不會被修改。

rebase: 一般稱之爲「衍合」,它經過修改提交歷史來對比雙方的commit,而後找出不一樣的去緩存,而後在去push,修改你的commit歷史。

cherry-pick: 用於將在其餘分支上的 commit 修改,移植到當前的分支(HEAD), -x 參數,表示保留原提交的做者信息進行提交。

git merge <branch> # 合併指定分支到當前分支

git rebase <branch> # 衍合指定分支到當前分支

# 用於將在其餘分支上的 commit 修改,移植到當前的分支(HEAD), <start-commit-id>…<end-commit-id>左開右閉,<start-commit-id>^…<end-commit-id>全閉
git cherry-pick <start-commit-id>…<end-commit-id>

11. 儲藏與清理

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

儲藏會處理工做目錄的髒的狀態 - 即,修改的跟蹤文件與暫存改動 - 而後將未完成的修改保存到一個棧上,而你能夠在任什麼時候候從新應用這些改動。

git add . && git stash # 將新的儲藏推送到棧上

git stash save 'message' # 儲藏修改,並留下stash信息

# -p(或-patch)容許交互選擇要提交的每一個跟蹤文件的各個部分。 這樣每一個提交只包含相關的更改。
git stash -p

# 默認狀況下,當存儲時,不包括未跟蹤的文件。 爲了更改該行爲幷包含這些文件,您須要使用-u參數。 還有-a(-all)能夠徹底存儲未跟蹤和忽略的文件,這多是您一般不須要的東西。
git stash -u

git stash list # 查看棧中全部暫存

git stash apply <stash_id> # 恢復復對應編號暫存到工做區,若是不指定編號爲棧頂的,注意:這些暫存還在棧中

git stash pop <stash_id> #將棧頂的暫存,恢復到工做區,並從棧中彈出,注意:這些暫存不在棧中

git stash drop <stash_id> # 移除的儲藏在棧中的東西

git stash clear #清空暫存棧

git stash branch <branch_name> # 從儲藏建立一個分支

12. 遠程操做

遠程倉庫是指託管在因特網或其餘網絡中的你的項目的版本庫。

git remote # 查看已配置的遠程倉庫服務器

git remote -v # 指定選項 -v,會顯示須要讀寫遠程倉庫使用的 Git 保存的簡寫與其對應的 URL。

git remote show <remote-name> # 查看制定遠程倉庫的更多信息

git remote add <shortname> <url> # 添加一個新的遠程 Git 倉庫

git remote rm <name> # 移除遠程倉庫

git remote rename <oldname> <newname># 重命名遠程倉庫

git fetch <remote-name> # 從遠程倉庫中拉取數據

# 下載代碼及快速合併, 當你想拉取origin服務器上的當前分支名的代碼時,可簡寫git pull
git pull <remote-name> <branch-name>

# 第一次推送到遠程倉庫,--set-upstream可簡寫爲-u
git push --set-upstream <remote-name> <branch-name>

# 推送到遠程倉庫, 當你想將當前開發分支名推送到 origin 服務器,可簡寫爲git push
git push <remote> <branch-name>

git push [remote] --force # 強行推送當前分支到遠程倉庫,即便有衝突

git push [remote] --all # 推送全部分支到遠程倉庫

git push <remote> :<branch-name/tag-name> # 刪除遠程分支或標籤

git push --tag # 上傳全部標籤

13. 衝突

# 一次打開全部衝突的文件,從新綁定可能會致使衝突,如下命令將打開須要您幫助解決這些衝突的全部文件。
git diff --name-only --diff-filter=U | uniq | xargs $EDITOR

從本地初始化到上傳到GitHub遠程倉庫的通常步驟

git init
git add .
git commit -m 'hint message'
git remote add origin 'your project repositories href on github'
git pull origin master
git push -u origin master

首次push遠程倉庫提交錯誤 -> 錯誤截圖解決詳見

error: failed to push some refs to 'https://github.com/xxx.git'
# --allow-unrelated-histories 合併了兩個不相關的項目的歷史記錄。
git pull origin master --allow-unrelated-histories

git push -u origin master

相關文章
相關標籤/搜索