Git命令總結和常見問題解決方案

說明

本篇文章是看Pro Git一書按照自己的思維模式對Git命令進行了分類。

一、Git配置

配置Git用戶名
git config --global user.name ""
配置Git郵箱
git config --global user.email ""
設置文本編譯器
git config --global core.editor
git config --global core.editor "'D:\Notepad++\notepad++.exe' -multiInst -notabbar -nosession -noPlugin '$*'"
差異分析工具
git config --global merge.tool vimdiff
設置git log的提交時間格式
git config --global log.date iso
查看配置信息
git config --list
git config --list --show-origin
查詢某項配置設置的值
git config user.email
git config --list --show-origin|grep "user.email"

注意事項:
參數–system、–global和–local依次爲針對所有用戶的配置、針對當前用戶的配置、針對當前git倉庫的配置,
如果存在同樣的配置優先級從高低爲:–local、–global、–system。

二、創建Git倉庫的兩種方式

初始化當前目錄爲Git倉庫
git init
克隆遠程倉庫到本地
git clone git@server-name:path/repo-name.git
不使用默認的origin倉庫名稱來跟着遠程倉庫,而是使用,其實就是給遠程開發起個別名。
git clone git@server-name:path/repo-name.git -o <name>
獲取遠程服務器上的裸倉庫,即複製遠程倉庫的.git目錄以及其中的文件到本地
git clone git@server-name:path/repo-name.git --bare

三、本地倉庫與遠程倉庫

將遠程倉庫的引用添加到本地倉庫中,origin爲遠程倉庫別名
git remote add origin git@server-name:path/repo-name.git
查看本地倉庫添加的遠程庫引用名稱
git remote
查看本地倉庫添加的遠程庫引用名稱和對應遠程倉庫URL
git remote -v
查看遠程分支詳細信息(遠程分支列表以及狀態、本地分支pull和push對應的遠程分支等)
git remote show [遠程倉庫引用名稱]
刪除本地倉庫中的遠程倉庫引用名稱
git remote rm [遠程倉庫引用名稱]
重命名遠程倉庫引用名稱。注意:之前origin/master訪問遠程分支,修改後origin-test/master訪問遠程分支。
git remote rename [原有遠程倉庫引用名稱] [新的遠程倉庫引用名稱]

四、提交

添加文件到暫存區(包括未跟蹤文件和已跟蹤文件)
git add <file-name>
添加文件到暫存區(只包括已跟蹤文件)
git add -u <file-name>
將暫存區中指定文件從暫存區提交到本地Git倉庫
git commit -m "commit desc" <file-name>
將暫存區中所有文件從暫存區提交到本地Git倉庫
git commit
*跳過暫存區直接提交到本地倉庫,相當於git add ;git commit.。注意此命令不會將未跟蹤(Untracked files)的文件提交到本地倉庫中。
git commit -a -m "commit desc"等同於git commit -am "commit desc"
查看本地Git倉庫狀態
git status

五、對比

工作區和暫存區的文件不同對比
git diff
暫存區和本地Git倉庫文件最後一次提交不同對比
git diff --cached <file-name> 等同於 git diff --staged <file-name>
工作區和本地Git倉庫文件最後一次提交不同對比
git diff HEAD <file-name>
比較當branch-a和branch-b兩個分支最新一次提交內容的不同,其實比較的是兩個提交的差異,應爲branch-a和branch-b都是指向最新的一次提交,也可以根據需要指定SHA-1來比較兩次提交差異
git diff <branch-a> <branch-b>
查可能存在的空白字符問題
git diff --check <file-name>
過濾掉空白字符的差異
git diff -b <file-name>
查看當前Git可使用以及支持哪些diff插件
git difftool --tool-help
使用指定的diff插件比較文件差異
git difftool --tool=vimdiff3

六、撤銷&回退

回退到上一次提交
git reset --soft HEAD~
解析:其實就是移動了HEAD的指向的commit對象
將已暫存的文件移除暫存區
git reset HEAD
解析:其實就是將HEAD指向最新一次更新,然後將倉庫最新一次提交更新到索引區,加上路徑會將提交快照中指定的文件移除暫存區。
將工作目錄所有文件回退到倉庫最新一次提交
git reset --hard HEAD
解析:其實就是將HEAD指向最新一次更新,然後將倉庫最新一次提交更新到索引區,將索引區內容更新到工作目錄)

注意:此命令沒有加上路徑的形式(git reset –hard HEAD fileA.txt)。

將工作目錄指定文件回退到倉庫最新一次提交快照中的文件
git checkout HEAD fiel.txt
切換分支
git checkout beanch-name
修改最近一次提交的文件和提說明。此命令執行後暫存區的文件將會被提交,並可以重新填寫說明,生成一個新的commit來覆蓋最近一次commit
git commit --amend

七、提交記錄查看

列出HEAD所指向的位置發生的變化(git commit、git checkout dev等命令會改變HEAD所指向的分支已經分支所指向的commit對象,reflog會列出這種變化)
其實就是你向git本地倉庫保存數據時產生一個SHA-1時,Git就會記錄這個操作,並可以使用git reflog 命令顯示這些操作歷史。
git reflog
查看第2條命令之後的命令記錄
git reflog HEAD@{2}
查看dev分支的歷史
git reflog dev
查看dev分支從第2條命令之後的命令記錄
git reflog dev@{2}
當前倉庫所有分支的提交歷史
git log --all
以reflog的方式查看提交歷史(提交歷史中多了Reflog信息)
git log -g
查看當前分支提交歷史以一個簡短的SHA-1值和提交說明
git log --oneline
查看合併的提交記錄(在提交歷史中查看以合併的提交記錄,也就是有兩個父commit對象的提交)
git log --merges
查看未合併的提交歷史記錄(在提交歷史中查看未合併的提交記錄,也就是除了有兩個父commit對象的提交之外的提交)
git log --no-merges

注意:–merges和–no-merges並不能查看某個分支是否合併到了當前分支,而是對已經合併的歷史記錄做過濾而已。

查看存在於iss11分支中的提交不在master分支中的提交(即有iss11分支有哪些提交未合併到master中)
git log masster..iss11
等同於git log master…iss11
git log ^master..iss11
存在iss11分支中的提交不存在master分支中的提交或存在於dev中的提交不存在master中的提交
git log iss11 dev ^master **存在各自分支中的並不同時包含的提交(兩個分支的並集)** git log iss11...master
查詢當前目錄24到25號兩天的提交記錄,並且以oneline形式顯示提交記錄、未合併的(–no-merges)、範圍在當前目錄下(./)的文件提交記錄
git log --after="2018-07-24" --before="2018-07-25" --pretty=oneline --no-merges -- ./
命令操作歷史記錄
gitk
按照提交時間顯示所有提交記錄
git log
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(後跟指定格式)。
			format選項說明:
				%H 提交對象(commit)的完整哈希字串
				%h 提交對象的簡短哈希字串
				%T 樹對象(tree)的完整哈希字串
				%t 樹對象的簡短哈希字串
				%P 父對象(parent)的完整哈希字串
				%p 父對象的簡短哈希字串
				%an 作者(author)的名字
				%ae 作者的電子郵件地址
				%ad 作者修訂日期(可以用 -date= 選項定製格式)
				%ar 作者修訂日期,按多久以前的方式顯示
				%cn 提交者(committer)的名字
				%ce 提交者的電子郵件地址
				%cd 提交日期
				%cr 提交日期,按多久以前的方式顯示
				%s 提交說明
	--date:指定提交歷史中的提交時間顯示格式,--date=iso、--date=local
	------過濾條件相關
    -(n):僅顯示最近的 n 條提交
    --since, --after:僅顯示指定時間之後的提交。
    --until, --before:僅顯示指定時間之前的提交。
    --author:僅顯示指定作者相關的提交。
    --committer:僅顯示指定提交者相關的提交。
	--grep:僅顯示含指定關鍵字的提交
	-S:僅顯示添加或移除了某個關鍵字的提交

八、從本地Git移除文件(不在進行Git版本管理)

從索引區中刪除文件,並標記爲文件在Git中已經刪除,工作目錄中的文件將不會收到影響,執行git commit - m "commit desc"命令級將rm操作提交到本地倉庫
git rm --cached <file-name>
此命令和帶有–cached功能選項作用相同,只不過文件會從本地磁盤中被刪除,執行git commit - m "commit desc"命令級將rm操作提交到本地倉庫
git rm <file-name>
文件重命名
git mv <file-name>

九、本地倉庫推送到遠程倉庫

推送當前分支到分支關聯的遠程倉庫分支
git push
推送本地倉庫分支到遠程倉庫分支,如果遠程倉庫沒有此分支會新建分支
git push [遠程倉庫名稱] [本地分支名稱]:[遠程分支名稱]
將本地分支推送到遠程倉庫分支。如果遠程倉庫沒有此分支會新建分支,並建立本地分支和遠程倉庫分支的關聯關係
git push --set-upstream [遠程倉庫名稱] [本地分支名稱]:[遠程分支名稱]
等同
git push -u [遠程倉庫名稱] [本地分支名稱]:[遠程分支名稱]

刪除遠程倉庫中的分支和本地對此遠程分支的引用,並不刪除本地的分支。從命令格式可以看出推送一個空的倉庫到遠程分支就達到了刪除的目的。
git push [遠程倉庫名稱] :[遠程分支名稱]

十、遠程倉庫拉取到本地倉庫

拉取當前分支關聯的遠程分支內容到本地
git pull
拉取遠程倉庫所有分支以及分支內容到本地倉庫中的分支(做合併)
git pull [遠程分支名稱]
拉取特定分支
git pull [遠程倉庫名稱] [本地分支]:[遠程分支名稱]

注意:git pull相當於git fetch+git merge。拉取過程中提示失敗,可能是本地Git倉庫內容和遠程倉庫內容不一致,會進入mergeing模式,使用git status命令會提示出哪些文件需要merge,人工進行merge後git commit即可。

抓取當前分支關聯的遠程分支內容到本地倉庫中的遠程分支引用分支
git fetch
從遠程倉庫抓取所有分支以及內容到本地倉庫中的遠程分支引用分支
git fetch [遠程倉庫名稱]
抓取特定分支
git fetch [遠程倉庫名稱] [遠程分支名]
如果遠程倉庫分支在本地沒有遠程分支引用會在本地新建這個遠程分支引用。例如:拉取遠程倉庫fetch-test分支到本地倉庫,本地倉庫不存在gitee-gitTest01/fetch-test則會新建。

Administrator@USER-20171018VX MINGW64 /d/gitTest/gitTest01 (iss11)
$ git fetch gitee-gitTest01 fetch-test
From https:gitee.com/superman-zhangxy/gitTest01
 * branch            fetch-test -> FETCH_HEAD
 * [new branch]      fetch-test -> gitee-gitTest01/fetch-test

十一、分支

git branch <branch-name>:創建分支
git checkout <branch-name>:切換分支
git checkout -b <branch-name>:創建分支並切換到創建的分支
git branch:查看所有分支

git branch -v:查看每一個分支最後一次提交
git branch -vv:查看本地倉庫分支和遠程倉庫分支對應關係以及每一個分支最後一次提交
git branch -r:查看遠程倉庫引用
git branch -a:查看本地分支和遠程倉庫分支引用(即列出所有分支)
git branch -vva:git branch -vv + git branch -a。
git branch --merge:查看哪些分支已經合併到當前分支。如果分支已經合併到當前分支刪除以合併的分支,刪除後也不會丟失文件版本,因爲已經合併到當前分支。
git branch --no-merges:查看哪些分支沒有合併到當前分支

git branch -d branch name:刪除分支(如果分支有文件修改而沒有merge會不讓刪除)
git branch -D branch name:強制刪除分支

git checkout -b dev origin/dev:在本地創建和遠程倉庫中對應的分支。

在本地倉庫分支和遠程倉庫分支建立關聯關係。也就是說git pull,git fetch,git push如果不指定遠程倉庫分支會作用於默認的本地倉庫分支對應的遠程倉庫分支。
git branch --set-upstream-to [遠程倉庫名稱]/[分支名稱] [本地分支名稱]

十二、合併

git merge <branch-name>:將指定分支合併到當前分支。
合併的結果有三種情況,詳見16.2小節。衝突的情況下Git會進入merge模式,需要我們手工修改文件來解決衝突。在這種模式下衝突的文件會有四種模式:base、ours、theirs和帶有衝突標記的存在工作目錄的文件模式。例如:需要將dev合併到master分支(git checkout master;git merge dev)時a.txt文件有衝突,兩個分支的共同的祖先commit中的a.txt是base版本,master分支中的a.txt就是ours(我們的)文件版本,dev分支中的a.txt就是theirs(他們的)文件版本,在工作目錄中通過<<<<<<< HEAD ====== >>>>>>> dev 標記的a.txt文件爲帶有衝突標記的存在工作目錄的文件模式。
工作目錄中衝突文件中的衝突標記也只標記ours和theirs版的不同,並不標記base版本中的衝突,這是因爲一般我們需要合併的代碼都在ours和theirs版本中,並不在base版本中。如果需要衝突文件中帶有base版本中的衝突標記可以使用git checkout --conflict=diff3 hello.rb命令,此命令不僅僅只給你 “ours” 和 “theirs” 版本,同時也會有 “base” 版本中的衝突,這回給你帶來更多上下文。

退出當前merge模式,退出後Git會回到運行此命令之前的狀態
git merge --abort
ours版本和合並後的結果做比較,即合併後的結果引入了ours哪些行,–base和–theirs選項同理
git diff --ours
使用我們版本作爲解決衝突方案,–theirs選項同理
git checkout --ours -- abc.txt

git merge --no-ff -m "<desc>" dev:不使用Fast-forward模式。
git merge --allow-unrelated-histories [分支名稱]:強制合併兩個不相關的分支。例如:我在本地創建了項目A,並添加了若干代碼,有在遠程倉庫創建了A倉庫,現在想將遠程A倉庫的master分支合併到本地的master分支會報錯:fatal: refusing to merge unrelated histories(致命的:拒絕合併不相關的歷史),使用此命令可解決報錯。

解決合併的衝突後,我們可能希望通過日誌查看提交的衝突是如何解決可以使用如下兩個命令:
git show SHA-1:SHA-1是一個合併產生的commit
git log --cc -p:合併的commit會顯示如何解決合併衝突的

十三、儲藏

git stash:將當前工作區(已跟蹤文件)和暫存區儲藏
git stash save "test stash":作用同 git stash,不過可以額外增加一些說明文字
git stash --keep-index:將當前工作區(已跟蹤文件)儲藏,不儲藏暫存區中的文件
git stash -ugit stash --include-untracked:將當前工作區(已跟蹤文件和未跟蹤)和暫存區儲藏
git stash --all:工作目錄(未跟蹤、已跟蹤)、忽略文件和暫存區都會被儲藏
git stash list:查儲藏工作區列表
git stash pop:恢復並刪除儲藏區
git stash apply:恢復儲藏區。添加 --index 參數會將暫存區的文件恢復到暫存區,否則所有文件將恢復到工作區,這不是我們想看到的。
git stash drop:刪除儲藏區
git stash show -p stash@{0}:儲藏中的文件與它上一個版本之間的差異比較(diff),並不是與當前工作目錄或git倉庫最後一次提交進行差異比較,而是儲藏文件時這些文件與他上一個版本之間的差異
git stash show stash@{0}:查看貯藏中的內容
git stash show -p stash@{0} | git apply -R:取消恢復的儲藏。stash@{0}爲儲藏名稱,不加名詞默認取消最近回覆的儲藏。
git stash branch <branch-name>:根據儲藏創建一個新分支

git stash應用場景:當前分支功能開發到一半時,又想去其它分支進行其它功能開發,又不想將當前分支文件提交到版本庫,使用 git stash儲藏當前分支文件,然後切換到其它分支工作。

注意:在恢復儲藏時分支的工作目錄不一定是需要乾淨的,如果儲藏中的文件和工作目錄中有衝突,git會提示我們合併。我們也可將儲藏應用在其它分支上。也就是說應用儲藏在一個乾淨的工作目錄和應用在創建儲藏所在的分支併成功應用儲藏的先決條件。

十四、標籤

給最近的commit打一個標籤(輕量標籤,lightweight)
git tag <tag-name>
給最近的commit打一個標籤,並給標籤添加描述(附註標籤,annotated)
git -a tag-name -m "tag desc"
給某次commit打一個標籤
git tag <tag-name> commit的SHA-1
查看所有標籤
git tag
查看符合條件的標籤名稱。查看標籤名稱以1.1開頭的標籤
git tag -l "1.1*"
刪除標籤
git tag -d <tag-name>
推送指定標籤到遠程倉庫
git push [遠程倉庫引用名稱] [標籤名稱]
推送所有標籤到遠程倉庫
git push origin --tags

一個輕量標籤很像一個不會改變的分支 - 它只是一個特定提交的引用。
然而,附註標籤是存儲在 Git 數據庫中的一個完整對象。 它們是可以被校驗的;其中包含打標籤者的名字、電子郵件地址、日期時間;還有一個標籤信息;並且可以使用 GNU Privacy Guard (GPG)簽名與驗證。 通常建議創建附註標籤,這樣你可以擁有以上所有信息;但是如果你只是想用一個臨時的標籤,或者因爲某些原因不想要保存那些信息,輕量標籤也是可用的。

十五、子模塊

項目中的子目錄不受項目git版本管理,有獨立的git版本管理。進入子模塊執行git add或git commit等命令是作用在子模塊的git版本管理,項目中(上層項目或主項目)文件不受影響,反之也是。

1,克隆一個子模塊
git submodule add [遠程倉庫地址] 遠程倉庫別名
2,克隆一個帶子模塊的項目
2.1 進入子模塊目錄執行如下命令初始化子模塊版本控制相關文件
git submodule init
2.2 進入子模塊目錄執行如下命令更新子模塊中的文件
git submodule update

十六、其它

交互式暫存命令
git add -i
獲取Git命令格式幫助
git help <verb>
git <verb> --help
列出Git在各種場景下常用的命令
git help

十七、底層命令

查看Git中任意存儲對象的內容
git cat-file -p SAH-1
查看Git中任意存儲對象的類型

git cat-file -t SAH-1

十六、常見問題

16.1 如何從每個提交快照中擦除指定文件
我們可能又有存心大意將帶有數據庫密碼的配置文件提交到了遠程倉庫,可以使用git filter-branch命令來從每個提交快照中擦除配置文件。如下事例:執行git filter-branch --tree-filter 'rm -f src/main/resources/database.properties' HEAD從每個快照中擦除database.properties文件。

Administrator@USER-20171018VX MINGW64 /d/gitee/baseMyBatis (temp)
$ pwd
/d/gitee/baseMyBatis
Administrator@USER-20171018VX MINGW64 /d/gitee/baseMyBatis (temp)
$ git filter-branch --tree-filter 'rm -f src/main/resources/database.properties' HEAD
Rewrite b1f7663b07a824436689522250472b4c2f8db4e4 (1/5) (0 seconds passed, remaining 0 predicted)
Rewrite 082a9c28d23f7953040a2e7d0a61d6c20170f8c8 (2/5) (2 seconds passed, remaining 3 predicted)
Rewrite e364f012ec4b99cb7029683b7b6514031ee3cba7 (2/5) (2 seconds passed, remaining 3 predicted)
Rewrite 5ca1207a2420cc9e138c6d82bd5bed30e211136e (4/5) (5 seconds passed, remaining 1 predicted)
Rewrite dd39df7876853977f9cb7396d89ec0001ec95d52 (5/5) (7 seconds passed, remaining 0 predicted)
Ref 'refs/heads/temp' was rewritten
Administrator@USER-20171018VX MINGW64 /d/gitee/baseMyBatis (temp)
$ ls src/main/resources/
mybatis3/  mybatis-config.xml
Administrator@USER-20171018VX MINGW64 /d/gitee/baseMyBatis (temp)
$ git log  --oneline
e3d1b11 (HEAD -> temp) 對項目添加說明信息
c12432e 不對IntelliJ IDEA IDE產生的文件進行Git關聯
56c17f1 Merge remote-tracking branch 'baseMyBatis/master' into temp
5d9f28e 一個使用MyBatis框架訪問數據庫的java程序
082a9c2 Initial commit

注意:1,不要在master分支做文件的擦除操作,要checkout一個新的分支,在新分支上做。2,在新分支擦除指定的文件後可以強行覆蓋master分支(即git reset --hard temp),如果使用git merge temp到master分支,會出現如圖的提交記錄,這並不是我們想要的。
在這裏插入圖片描述
16.2 將遠程分支在本地的引用合併到本地的分支(git checkout master;git merge origin/master),合併結果分爲三種情況
1, 在修改代碼期間沒有其他開發人員向服務器推送修改,可進行快進(Fast forward)合併。
2,在修改代碼期間還有其他開發人員向服務器推送修改,如果推送和修改的文件有交集,合併就會有衝突,需要手工修改文件解決衝突。
3,在修改代碼期間還有其他開發人員向服務器推送修改,如果推送和修改的文件不交集,就會進行一次遞歸合併。
快進(Fast forward)的條件?
順着一個分支走下去可以到達另一個分支的話,那麼Git在合併兩者是,只會簡單地把指針右移,因爲這種單線的歷史分支不存在任何需要解決的分歧,所以這種合併過程可以稱爲快進(Fast forward)。
如果將test分支合併到master分支就可以進行合併。

	 master   	test
	   |       	 |
——C1<——C2<——C3<——C4
合併後的
	        	test
	          	 |
——C1<——C2<——C3<——C4
				 |
				master

16.3 使用Git向服務器推送代碼步驟(假設我們在本地的master分支中)
1,git fetch抓取服務器分支的狀態到本地的遠程引用分支(即origin/master)。
2,git master origin/master將遠程分支master合併到本地master分支。
3,合併成功後git push推送到服務器。
注意:步驟1和2可以使用git pull命令來完成。

16.4 如何將本地新建的項目push到遠程倉庫

  1. 在代碼託管網站新建倉庫,如下圖:
    在這裏插入圖片描述
  2. 在本地項目根目錄執行 git init命令,將項目變成一個git項目。
  3. 添加遠程倉庫的引用到本地。LSMS-MS是引用遠程倉庫的別名。
git remote add LSMS-MS http://ip:port/zhangxy/LSMS-ManagementSystem.git
  1. 推送本地項目到遠程倉庫LSMS-MS。
git push -u LSMS-MS master:master
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章