最近工作經(jīng)常使用Git陆错,本文重點總結(jié)歸納一下git經(jīng)常使用的命令和用法,以及對git基本原理的理解。
一葫辐、Git安裝后配置
1.1 用戶信息
安裝后要做的第一件事就是設(shè)置你的用戶名和郵箱地址章喉,因為每一個 Git 的提交都會使用這些信息汗贫,并且它會寫入到你的每一次提交中,不可更改:
$ git config --global user.name "adonfu"
$ git config --global user.email adon@example.com
- 若使用--global 選項秸脱,該命令只需要運行一次落包,Git 都會使用那些信息;
- 若針對特定項目使用不同的用戶名稱與郵件地址時摊唇,可以在那個項目目錄下運行沒有--global 選項的命令來配置咐蝇。
1.2 Git配置信息存儲在三個不同的位置
- /etc/gitconfig 文件: 包含系統(tǒng)上每一個用戶及他們倉庫的通用配置
若git config 使用選項 --system 時,會從此文件讀寫配置變量巷查。 - ~/.gitconfig 或 ~/.config/git/config 文件:只針對當(dāng)前用戶
若使用 --global 選項嘹害,Git讀寫此文件。 - .git/config:當(dāng)前倉庫吮便。
每一個級別覆蓋上一級別的配置笔呀,所以 .git/config 的配置變量會覆蓋 /etc/gitconfig 中的配置變量。
1.3 查看配置信息
$ git config --list
二髓需、基本命令
1. 獲取Git倉庫
有兩種方法取得Git項目倉庫许师。
1.1 在現(xiàn)有項目或目錄下導(dǎo)入所有文件到Git中
若目錄gitCmdTest已創(chuàng)建,執(zhí)行如下命令:
$ cd gitCmdTest
$ git init
若要初始化一個新的版本庫~/gitCmdTest/.git/:
$ git init gitCmdTest
1.2 從一個服務(wù)器克隆一個現(xiàn)有的Git倉庫
克隆倉庫的命令格式是git clone [url]
$ git clone https://github.com/fuyadong/firstProject
在當(dāng)前目錄下創(chuàng)建一個firstProject目錄僚匆,在這個目錄下初始化一個.git文件夾微渠,保存遠程倉庫的所有數(shù)據(jù)。
若將遠程倉庫自定義本地倉庫:
$ git clone https://github.com/fuyadong/firstProject myproject
1.3 將文件放入版本庫
$ touch file1.py #創(chuàng)建文件file1
$ touch file2.py #創(chuàng)建文件file2
$ git add . #將當(dāng)前路徑下所有修改/新增的文件加入代碼庫
$ git add file1.py file2.py #單個文件添加
$ git add LICENSE
$ git commit -m 'some message' #提交代碼
$ git diff #比較當(dāng)前修改的文件與之前的區(qū)別
$ git status #查看狀態(tài)
1.4 設(shè)置忽略文件
有些文件無需納入Git 的管理咧擂,也不希望它們總出現(xiàn)在未跟蹤文件列表逞盆。通常都是些自動生成的文件,比如日志文件松申,或者編譯過程中創(chuàng)建的臨時文件等云芦。
1.4.1 設(shè)置整個項目要忽略的文件
在根目錄新建一個文件.gitignore俯逾,列出要忽略的文件模式。
$ touch .gitignore
$ echo *.[oa] > .gitignore
$ echo *~ > .gitignore
將.gitignore文件加入版本庫并提交舅逸。
1.4.2 設(shè)置自己項目要忽略的文件
修改.git/info/exclude文件桌肴,設(shè)置要忽略的文件:
*.[oa]
*~
還可以忽略 log,tmp 或者 pid 目錄琉历,以及自動生成的文檔等坠七。
1.4.3 .gitignore 的格式規(guī)范
格式規(guī)范如下:
- 所有空行或者以 # 開頭的行都會被 Git 忽略。
- 可以使用標準的 glob 模式匹配旗笔。
- 匹配模式可以以(/)開頭防止遞歸彪置。
- 匹配模式可以以(/)結(jié)尾指定目錄。
- 要忽略指定模式以外的文件或目錄蝇恶,可以在模式前加上驚嘆號(!)取反悉稠。
glob 模式是簡化的 shell 正則表達式:
- 星號(*)匹配零個或多個任意字符;
- [abc] 匹配任何一個列在方括號中的字符艘包;
- 問號(?)只匹配一個任意字符的猛;
- 在方括號中使用短劃線分隔兩個字符,表示所有在這兩個字符范圍內(nèi)的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的數(shù)字想虎;
- 使用兩個星號(*) 表示匹配任意中間目錄卦尊,比如
a/**/z
可以匹配 a/z, a/b/z 或a/b/c/z
等。
不同項目及語言的.gitignore文件列表gitignore
2. 本地操作
2.1 提交操作
使用git add建立跟蹤舌厨,將修改或新增的文件添加到暫存區(qū):
$ git add file1.py
使用git status查詢暫存狀態(tài):
$ git status
若不想暫存文件file1.py岂却,運行如下命令撤出暫存區(qū):
$ git reset HEAD file1.py
后悔操作:
$ git reset HEAD^ # 恢復(fù)到上一個版本
$ git reset HEAD^ file1.py # 將文件回退到上一個版本
$ git reset -soft HEAD~n # 回退到第n個版本
$ git reset <object key> # 回退到具體的提交對象
$ git reset -hard origin/master # 將本地狀態(tài)與遠程master庫一致
將暫存區(qū)的內(nèi)容提交更新:
$ git commit -m 'msg'
提交時記錄的是放在暫存區(qū)域的快照。任何還未暫存的仍然保持已修改狀態(tài)裙椭,可以在下次提交時納入版本管理躏哩。每一次運行提交操作,都是對你項目作一次快照揉燃,以后可以回到這個狀態(tài)或者進行比較扫尺。
若已跟蹤的文件被修改,可以使用參數(shù)-a將修改的文件暫存并提交:
$ git commit -a -m 'msg'
2.2 移除文件
若要刪除已暫存的文件(從暫存區(qū)移除):
$ rm file.py
$ git rm file.py
再提交時炊汤,文件file.py就不會納入到版本管理正驻。
若要將已經(jīng)提交到版本庫中的文件移除,但希望保留在當(dāng)前工作目錄中抢腐,使用選項--cached
:
$ git rm --cached file.py
手動刪除姑曙,將文件撤出暫存區(qū):
$ rm file.py
可以使用git status
命名查看狀態(tài)。
文件重命名操作:
$ git mv filename.py file.py
相對于如下操作:
$ mv filename.py file.py
$ git rm filename.py
$ git add file.py
2.3 工作區(qū)文件狀態(tài)
工作目錄下每個文件有兩個狀態(tài):已跟蹤或未跟蹤迈倍。
- 已跟蹤的文件:被納入了版本控制的文件伤靠,在上一次快照中有它們的記錄,在工作一段時間后啼染,它們的狀態(tài)可能處于未修改宴合,已修改或已放入暫存區(qū)焕梅。
- 未跟蹤文件:除已跟蹤的文件以外的所有其它文件。它們既不存在于上次快照的記錄中形纺,也沒有放入暫存區(qū)。
- 初次克隆的倉庫徒欣,工作目錄中的所有文件都屬于已跟蹤文件逐样,并處于未修改狀態(tài)。
文件狀態(tài)變化:
git add 建立跟蹤打肝,放入暫存區(qū)脂新;
git commit 將暫存區(qū)中的文件納入到版本管理;
2.4 撤消操作
若漏提文件或提交信息寫錯粗梭,可以使用參數(shù)--amend重新提交:
$ git commit --amend
示例:
$ git commit -m 'initial commit'
$ git add some_file
$ git commit --amend
最終只有一個提交 - 第二次提交將代替第一次提交的結(jié)果争便。
撤銷對文件的修改:
$ git checkout -- file.py
$ git checkout HEAD file.py
$ git checkout HEAD *.py
$ git checkout HEAD .
3. 遠程倉庫操作
3.1 創(chuàng)建遠程倉庫
- 可以通過github創(chuàng)建一個遠程倉庫,使用
git clone
命令克隆版本庫断医。
git clone https://github.com/fuyadong/firstProject
自動添加的配置信息滞乙,通過命名git config --list
查看。
- 通過命令行創(chuàng)建版本庫:
$ git remote add origin remote_git_server_address
顯示遠程倉庫的名字和URL:
$ git remote -v
3.2 從遠程倉庫中抓取與拉取
從遠程倉庫中獲得數(shù)據(jù):
$ git fetch [remote-name]
若版本庫通過git clone
命令獲取鉴嗤,倉庫名稱remote-name默認為origin斩启。
3.3 推送到遠程倉庫
命令格式:git push [remote-name] [branch-name]
首先確保克隆服務(wù)器有寫入權(quán)限醉锅。
$ git push origin master
若版本庫使用其他名稱pub:
$ git remote add pub https://github.com/fuyadong/firstProject
$ git push -u pub master
-u表示使用某個遠程倉庫兔簇,默認的遠程庫,設(shè)置一次即可硬耍。
3.4 查看遠程倉庫
$ git remote show origin
3.5 遠程倉庫重命名和移除
$ git remote rename pub publish
$ git remote rm publish
4 分支
Git分支是指向提交對象的可變指針垄琐,默認分支名字是master,始終指向最新的提交對象经柴,自動向前移動狸窘。與其他分支完全沒有區(qū)別,由git init
命令默認創(chuàng)建坯认。
特殊指針HEAD:指向工作空間當(dāng)前所在的本地分支朦前,這樣Git就知道當(dāng)前是在哪個分支上。
4.1 創(chuàng)建分支
$ git branch dev
創(chuàng)建一個新分支dev鹃操,并不會自動切換到新分支中去韭寸。
查看分支當(dāng)前所指對象:
$ git log --oneline --decorate
查看分叉歷史:
$ git log --oneline --decorate --graph --all
可以看到提交歷史、各個分支的指向以及項目的分支分叉情況荆隘。
4.2 切換分支
切換到分支dev:
$ git checkout dev
新建并切換分支:
$ git checkout -b dev
4.3 刪除分支
$ git branch -d dev
4.4 分支管理
$ git branch # 查看本地分支
$ git branch -r # 查看遠程分支
$ git branch -v # 查看每個分支的最后一次提交
查看哪些分支已經(jīng)合并到當(dāng)前分支:
$ git branch --merged
查看所有包含未合并工作的分支:
$ git branch --no-merged
4.5 合并分支
將分支dev合并入master分支:
$ git checkout master
$ git merge dev
4.6 解決合并沖突
Git在發(fā)生沖突的文件中會加入標準的沖突解決標記恩伺,可以手動解決沖突,如下一段內(nèi)容:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> dev:index.html
在======= 的上半部分是HEAD 所指示的版本椰拒,即HEAD所在的分支晶渠;在 ======= 的下半部分凰荚,是dev分支所指示的版本;這是可以選擇一部分保留褒脯,也可手動解決沖突便瑟,然后刪除沖突標記。使用git add
命令標記沖突已解決番川。
4.7 遠程分支
4.7.1 跟蹤分支
在遠程跟蹤分支基礎(chǔ)上到涂,建立本地分支:
$ git checkout -b dev origin/dev
本地分支dev自動從origin/dev拉取,命令格式:git checkout -b [分支名] [遠程名]/[分支名]颁督。
跟蹤分支:從一個遠程跟蹤分支檢出一個本地分支會自動創(chuàng)建一個叫做 “跟蹤分支”(有時候也叫做 “上游分支”)践啄。 跟蹤分支是與遠程分支有直接聯(lián)系的本地分支。
在一個跟蹤分支上執(zhí)行:
git push
命令:Git會自行推斷應(yīng)該向哪個服務(wù)器的哪個分支推送數(shù)據(jù)沉御;
git pull
命令:Git能自動地識別去哪個服務(wù)器上抓取屿讽、合并到哪個分支。
在執(zhí)行git clone
時吠裆,Git通常會自動創(chuàng)建一個名為master的分支來跟蹤origin/master伐谈。
4.7.2 查看設(shè)置的所有跟蹤分支
$ git branch -vv
列出所有本地分支及其每個分支正在跟蹤哪個遠程分支。
4.7.3 推送分支
$ git push origin master
將master分支推送到遠程倉庫origin上试疙。
4.7.4 獲取服務(wù)器數(shù)據(jù)
$ git fetch
從服務(wù)器上抓取本地沒有的數(shù)據(jù)衩婚,并不會合并;需要執(zhí)行git merge
命令效斑。
4.7.5 刪除遠程分支
$ git push origin --delete remote_branch
5 標簽
可以使用打標簽功能來標記發(fā)布節(jié)點非春,比如發(fā)布版本的時候。也可以為某個提交打標簽缓屠。
5.1 查看標簽
$ git tag
$ git tag -l 'v2.0*'
5.2 創(chuàng)建標簽
創(chuàng)建附注標簽:
$ git tag -a v2.0 -m 'my version 2.0'
通過使用git show
命令可以看到標簽信息與對應(yīng)的提交信息奇昙。
輕量標簽本質(zhì)上是將提交校驗和存儲到一個文件中,沒有保存任何其他信息敌完。創(chuàng)建輕量標簽储耐,不需要使用-a
、-s
或-m
選項滨溉,只需要提供標簽名字:
$ git tag v2.0-lw
輕量標簽和附注標簽區(qū)別:
一個輕量標簽很像一個不會改變的分支什湘,它只是一個特定提交的引用。
附注標簽是存儲在Git數(shù)據(jù)庫中的一個完整對象晦攒。它們是可以被校驗的闽撤;其中包含打標簽者的名字、電子郵件地址脯颜、日期時間和標簽信息哟旗。通常使用附注標簽,這樣可以看到以上信息。
5.3 后期打標簽
可以為之前的提交打標簽:
$ git log --pretty=oneline
$ git tag -a v1.2 8fceb05
$ git show v1.2
5.4 共享標簽
默認情況下闸餐,git push
命令并不會傳送標簽到遠程倉庫服務(wù)器上饱亮,在創(chuàng)建完標簽后你必須顯式地推送標簽到共享服務(wù)器上。
$ git push origin v1.2
將不再遠程倉庫服務(wù)器上的標簽全部推送到服務(wù)器上:
$ git push origin --tags
根據(jù)特定的標簽版本創(chuàng)建一個分支:
$ git checkout -b dev v2.0
命令格式:git checkout -b branch tag
三舍沙、Git基本原理
Git不僅僅是一個版本控制系統(tǒng)近上,它同時是一個非常強大且易用的工具,是一個內(nèi)容尋址文件系統(tǒng)拂铡。這里只介紹Git內(nèi)部的對象壹无,以更好的理解上面的命令。
Git對象
三個對象模型:
- blob對象:保存文件快照
- Tree對象:記錄目錄結(jié)構(gòu)和blob對象索引
- 提交對象:包含樹對象指針和提交信息
提交信息有作者的姓名和郵箱和媳、提交時輸入的信息以及指向它的父對象的指針格遭。首次提交產(chǎn)生的提交對象沒有父對象哈街,普通提交操作產(chǎn)生的提交對象有一個父對象留瞳,而由多個分支合并產(chǎn)生的提交對象有多個父對象。
執(zhí)行一次git commit
提交操作骚秦,Git會先計算每一個子目錄的校驗和她倘,然后在 Git 倉庫中這些校驗和保存為樹對象。 隨后作箍,Git 便會創(chuàng)建一個提交對象硬梁,對版本庫做一次快照。
可以使用如下命令查詢提交信息:
$ git log # 獲取提交記錄
$ git ls-tree <object key> # 查看指定對象所有信息
$ git cat-file -p <object key> # 獲取key對應(yīng)object的內(nèi)容胞得,根據(jù)object里面的內(nèi)容荧止,繼續(xù)探索,訪問到所有關(guān)聯(lián)object阶剑。
參考資料:
[1]: git book官網(wǎng) Git Book 跃巡。