安裝Git
Linux
|
$ sudo yum install git 或者 $ sudo apt-get install git |
Mac
直接在Terminal 執(zhí)行git 命令, 如果沒有會(huì)提示安裝方法.
如果喜歡安裝程序的話, 點(diǎn)這里
配置文件
第一次安裝, 千萬別要忘了配置你的git的使用者名字和郵箱. 這個(gè)道理很簡單, 每一次的提交時(shí)需要記錄提交者的, 如果沒有提交者, 那么bug出現(xiàn)找誰來背鍋??
查看config
Git 自帶一個(gè) git config 的工具來幫助設(shè)置控制 Git 外觀和行為的配置變量。
|
/etc/gitconfig 文件: 包含系統(tǒng)上每一個(gè)用戶及他們倉庫的通用配置。 $ git config --system --list ~/.gitconfig 或 ~/.config/git/config 文件:只針對當(dāng)前用戶。 $ git config --global --list |
當(dāng)前使用倉庫的 Git 目錄中的 config 文件(就是 .git/config ):針對該倉庫。
每一個(gè)級別覆蓋上一級別的配置,所以.git/config 的配置變量會(huì)覆蓋/etc/gitconfig 中的配置變量。
當(dāng)然, 也可以查看某一項(xiàng)配置信息.
- 形式:
git config [--global|--system]
|
查看最終的配置屬性值 $ git config user.name 查看當(dāng)前系統(tǒng)的屬性值 $ git config --global user.name |
設(shè)置用戶信息
|
$ git config --global user.name "name" $ git config --global user.email xxx@163.com |
使用--global 選項(xiàng), 當(dāng)以后在該系統(tǒng)上做的任何操作都會(huì)使用此屬性. 如果你需要在某一個(gè)特定的項(xiàng)目使用其他名字和郵箱, 那么可以通過設(shè)置項(xiàng)目中的config文件, 這樣config中的屬性會(huì)覆蓋掉global的全局屬性, 并且當(dāng)在其他項(xiàng)目中并不會(huì)造成影響. 使用方式只需要去掉--global 參數(shù)即可修改項(xiàng)目中的.git/config 文件
|
$ git config user.name "name" |
獲取幫助手冊
形式: git help 或者 git --help
比如查看config手冊
Git別名
例如: 生成別名之后可以在日后用簡短的表示來使用
|
$ git config --global alias.br branch $ git config --global alias.ci commit $ git config --global alias.st status |
.gitignore文件
對于自動(dòng)生成的文件, 日志, 編譯的臨時(shí)文件等. 可以對其進(jìn)行配置, 讓git不追蹤這些文件
規(guī)范如下:
- 所有空行或者以 # 開頭的行都會(huì)被 Git 忽略。
- 可以使用標(biāo)準(zhǔn)的 glob 模式匹配。
- 匹配模式可以以(/)開頭防止遞歸。
- 匹配模式可以以(/)結(jié)尾指定目錄。
- 要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(!)取反
glob模式 是指shell所使用的簡化了的正則表達(dá)式.
* :匹配零個(gè)或多個(gè)任意字符
[abc] :只匹配括號內(nèi)的任意一個(gè)字符
[0-9] :使用短劃線表示范圍, 可以匹配0到9之間的任何字符.
:匹配任意一個(gè)字符
** :匹配任意的中間目錄,例如a/**/z 可以匹配a/z ,a/b/z ,a/b/c/z 等
如下給出一個(gè)樣板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
# 忽略所有以 .c結(jié)尾的文件 *.c # 但是 stream.c 會(huì)被git追蹤 !stream.c # 只忽略當(dāng)前文件夾下的TODO文件, 不包括其他文件夾下的TODO例如: subdir/TODO /TODO # 忽略所有在build文件夾下的文件 build/ # 忽略 doc/notes.txt, 但不包括多層下.txt例如: doc/server/arch.txt doc/*.txt # 忽略所有在doc目錄下的.pdf文件 doc/**/*.pdf |
倉庫的基礎(chǔ)操作
初始化倉庫
添加文件到暫存區(qū)
|
# 添加全部暫存區(qū)和歷史區(qū)不存在的或者有更改的 `.c`結(jié)尾的文件 $ git add *.c # 添加全部暫存區(qū)和歷史區(qū)不存在的或者有更改的文件 $ git add . # 指定文件添加 $ git add test.c |
status倉庫
|
$ git status # 如果需要顯示一種緊湊式格式 $ git status --short # 等價(jià)于 $ git status -s |
緊湊式中字母的表示含義如下:
:表示新添加的未追蹤的文件
M :M出現(xiàn)在右邊,表示該文件被修改但是還沒有放入暫存區(qū)
M :M出現(xiàn)在左邊,表示文件被修改已經(jīng)放入了暫存區(qū)
MM :出現(xiàn)兩個(gè),代表此文件在工作區(qū)修改已經(jīng)放入了暫存區(qū), 但之后有進(jìn)行了修改,沒有添加到暫存區(qū)
diff倉庫
如果你想知道文件具體修改的內(nèi)容, 那么diff 會(huì)很有用
|
# 查看以追蹤但尚未暫存的文件更新了哪些部分, 不添加額外參數(shù) $ git diff # 對使用了add添加到了暫存區(qū)的內(nèi)容, 使用--staged參數(shù)或者--cached $ git diff --staged |
提交更新
|
# 常規(guī)做法 $ git commit -m "commit message" # 如果不使用-m參數(shù)添加提交信息, git會(huì)使用默認(rèn)的編譯器如vi進(jìn)行提交描述編寫. # 可通過$ git config --global core.edit 設(shè)定喜歡的編譯器 # 跳過暫存區(qū)操作, 直接從工作區(qū)提交到歷史區(qū) $ git commit -a -m "" #等價(jià)于: $ git commit -am "" |
移除文件
如果在工作區(qū)間對一個(gè)文件進(jìn)行刪除, 需要先進(jìn)行add ,然后才可以提交. 使用git rm 可以直接在工作區(qū)間刪除文件, 并提交到暫存區(qū).
|
$ git rm fileName # 如果文件修改,并添加了暫存區(qū), 需要使用-f參數(shù)來強(qiáng)制刪除(force) $ git rm -f fileName # 可以使用glob模式,如下 $ git rm log/*.log # 刪除log目錄下所有名稱是.log結(jié)尾文件 $ git rm *~ # 刪除以~結(jié)尾的所有文件 |
移動(dòng)文件
同樣使用git rm 會(huì)方便很多, 并且如果相對文件重命名也可以如此
|
$ git mv file_from file_to |
當(dāng)執(zhí)行了這條語句之后, 只需要在下一次commit 即可, 不需要考慮額外操作. 等價(jià)于如下:
|
$ mv file_from file_to $ git rm file_from $ git rm file_to |
查看歷史提交
如果是最基本的git log , 那么會(huì)按提交時(shí)間列出所有更新, 包括提交的SHA-1校驗(yàn)和, 作者名稱,郵箱,提交時(shí)間,提交說明. 下面說說常用選項(xiàng).
|
# -p:僅顯示最近x次的提交 格式 $ git log -p -x $ git log -p -2 # 查看最近的兩次提交內(nèi)容 # --stat:簡略的顯示每次提交的內(nèi)容更改, 如哪些文件變更,多少刪除,多少添加等 $ git log --stat # --pretty: 指定默認(rèn)不同格式展示信息 $ git log --pretty=oneline #每次提交用一行顯示 $ git log --pretty=format:"%h - %an, %ar : %s" # 效果:1a99c42 - 蘇, 19 hours ago : 無意義提交 |
關(guān)于format 對應(yīng)的常用占位符的寫法和意義
選項(xiàng) |
說明 |
%H |
提交對象(commit)的完整哈希字串 |
%h |
提交對象的簡短哈希字串 |
%T |
樹對象(tree)的完整哈希字串 |
%t |
樹對象的簡短哈希字串 |
%P |
父對象(parent)的完整哈希字串 |
%p |
父對象的簡短哈希字串 |
%an |
作者(author)的名字 |
%ae |
作者的電子郵件地址 |
%ad |
作者修訂日期(可以用 –date= 選項(xiàng)定制格式) |
%ar |
作者修訂日期,按多久以前的方式顯示 |
%cn |
提交者(committer)的名字 |
%ce |
提交者的電子郵件地址 |
%cd |
提交日期 |
%cr |
提交日期,按多久以前的方式顯示 |
%s |
提交說明 |
圖形展示分支的合并歷史
|
$ git log --graph --oneline #oneline只是讓輸出看起來比較舒服 |
git log的一些其他操作
選項(xiàng) |
說明 |
-p |
按補(bǔ)丁格式顯示每個(gè)更新之間的差異。 |
–stat |
顯示每次更新的文件修改統(tǒng)計(jì)信息。 |
–shortstat |
只顯示 –stat 中最后的行數(shù)修改添加移除統(tǒng)計(jì)。 |
–name-only |
僅在提交信息后顯示已修改的文件清單。 |
–name-status |
顯示新增、修改、刪除的文件清單。 |
–abbrev-commit |
僅顯示 SHA-1 的前幾個(gè)字符,而非所有的 40 個(gè)字符。 |
–relative-date |
使用較短的相對時(shí)間顯示(比如,“2 weeks ago”)。 |
–graph |
顯示 ASCII 圖形表示的分支合并歷史。 |
–pretty |
使用其他格式顯示歷史提交信息??捎玫倪x項(xiàng)包括 oneline,short,full,fuller 和 format(后跟指定格式)。 |
查找一個(gè)字符串的出現(xiàn)和刪除的提交
|
# 使用限制符-S后面緊跟要查詢的字符串 $ git log -Smethod_name # 或者針對一個(gè)文件進(jìn)行更改的提交查詢, 只需要在后面追加文件名稱即可 $ git log fileName |
哈哈,即使如果你不小心寫個(gè)隱藏bug不管幾個(gè)月之后,如果老大要想找出問題是寫引發(fā)的其實(shí)很簡單.例如這樣
$ git log -p fileName 想甩鍋?算了吧,還是認(rèn)錯(cuò)以后多注意吧.
還有一些限制log輸出的選項(xiàng)
選項(xiàng) |
說明 |
-(n) |
僅顯示最近的 n 條提交 |
–since, –after |
僅顯示指定時(shí)間之后的提交。 |
–until, –before |
僅顯示指定時(shí)間之前的提交。 |
–author |
僅顯示指定作者相關(guān)的提交。 |
–committer |
僅顯示指定提交者相關(guān)的提交。 |
–grep |
僅顯示含指定關(guān)鍵字的提交 |
-S |
僅顯示添加或移除了某個(gè)關(guān)鍵字的提交 |
一個(gè)實(shí)際的例子,如果要查看 Git 倉庫中,2016 年 11 月1號到7號,作者叫蘇的提交文件,可以用下面的查詢命令:
|
git log --pretty="%h - %s" --author=蘇 --since="2016-11-01" --before="2016-11-07" |
撤銷操作
amend重新提交
當(dāng)我們commit 之后突然發(fā)現(xiàn)漏掉了一個(gè)文件, 這個(gè)時(shí)候不可能對一個(gè)文件再進(jìn)行commit 一次, 這樣做就顯得很多余, 而如果版本回退之前再添加也比較麻煩. 這個(gè)時(shí)候就可以使用這個(gè)amend 命令.如下:
|
$ git commit -m "版本1.5開發(fā)代碼" # 正當(dāng)你松了一口氣的時(shí)候發(fā)現(xiàn)配置文件忘記修改了, 你趕緊修改,并適合用add到暫存區(qū) $ git add project.property $ git commit --amend # 你會(huì)神奇的發(fā)現(xiàn)你沒有增加任何多余的操作就把漏掉的文件補(bǔ)齊到最后一次提交中 |
取消暫存的文件
就是對文件進(jìn)行了git add 操作. 這個(gè)時(shí)候可以reset
|
# 讓暫存區(qū)的文件變成文件修改但是沒有添加暫存區(qū)的狀態(tài) $ git reset HEAD fileName |
撤銷對文件的修改
場景: 當(dāng)文件修改了, 但是還沒有進(jìn)行git add 的時(shí)候還只是在工作區(qū)間, 還原成最后一次提交的內(nèi)容
|
$ git checkout -- filename |
要注意使用, 使用之前確定是否要拋棄已經(jīng)添加的內(nèi)容. 因?yàn)檫@個(gè)動(dòng)作可能讓你最新添加的內(nèi)容徹底丟失. 因?yàn)闆]有進(jìn)行commit , 一般來說進(jìn)行了commit 的內(nèi)容都是可以恢復(fù)的.
標(biāo)簽
Git可以給歷史中的某一個(gè)提交打上標(biāo)簽, 以示重要. 比如每次正式版本的上線等.
列出標(biāo)簽
|
$ git tag # 如果你只關(guān)心某一部分的標(biāo)簽, 例如只對v2.x的標(biāo)簽感興趣,你可以這樣做 $ git tag -l 'v2.*' |
創(chuàng)建標(biāo)簽
標(biāo)簽分為兩種一種是附加標(biāo)簽 另一種是輕量標(biāo)簽 .
- 附加標(biāo)簽: 會(huì)保存打標(biāo)簽者的信息, 時(shí)間和附加信息. 最后更隨打標(biāo)簽的提交
- 輕量標(biāo)簽: 只是在一個(gè)提交上做一個(gè)標(biāo)記. 存儲(chǔ)在一個(gè)專門保存標(biāo)簽的文件,指向提交的hash值
先來看附加標(biāo)簽:
|
$ git tag -a v1.0 -m '附加信息' |
輕量標(biāo)簽
后期打標(biāo)簽, 就是對已經(jīng)提交某次提交進(jìn)行追加標(biāo)簽設(shè)置
|
# 可以先使用git log --oneline獲取提交歷史的hash值 $ git log --oneline # 然后把hash值賦值到標(biāo)簽語句之后 $ git tag -a v1.1 a6b4c97 |
共享標(biāo)簽
默認(rèn)情況下, git push 不會(huì)把標(biāo)簽傳遞到遠(yuǎn)程服務(wù)器. 需要顯示的推送標(biāo)簽共享到服務(wù)器
例如: git push origin [tagname]
|
$ git push origin v1.4 # 如果想把本地上所有在遠(yuǎn)程服務(wù)器上的不存在標(biāo)簽刪除掉,可以這樣 $ git push origin --tags |
檢出標(biāo)簽
git中不能真正的檢出一個(gè)標(biāo)簽, 但是可以在標(biāo)簽處創(chuàng)建一個(gè)新的分支.如下
|
$ git checkout -b checkbranch2 v2.0 |
查看標(biāo)簽對應(yīng)的信息
使用git show 可以查看對應(yīng)標(biāo)簽的詳細(xì)信息, 如果git show 這樣的命令只是顯示上次提交的內(nèi)容
分支操作
分支的創(chuàng)建
分支的創(chuàng)建, 其實(shí)本質(zhì)就是創(chuàng)建一個(gè)可以移動(dòng)的指針,這個(gè)指針名就是新的分支名
|
$ git branch dev # 上面的只是創(chuàng)建了一個(gè)分支. 并沒有切換, 可以使用一條命令創(chuàng)建并且換到新分支 $ git checkout -b dev # 可以通過`git log`命令查看各個(gè)分支所指向的對象 $ git log --oneline --decorate # 如果你想查看圖形式的分叉歷史,可以這樣: $ git log --oneline --decorate --graph --all |
分支的切換
所謂的分支切換就是HEAD 指針的指向的改變
分支合并
利用git merge , 這條命令會(huì)把當(dāng)前所在分支與目標(biāo)分支的內(nèi)容合并, 可以這樣理解, 如果當(dāng)你試圖向目標(biāo)分支合并時(shí), 如果當(dāng)前分支可以順著一個(gè)分支走下去, 那么本質(zhì)上其實(shí)只是當(dāng)前指針的向前移動(dòng), 由于這種情況下的合并并沒有需要解決的分期, 所以git會(huì)稱這個(gè)是fast-forward 快速前進(jìn).
刪除分支
當(dāng)一個(gè)功能分支開發(fā)完畢之后, 并進(jìn)行了合并, 通常這個(gè)分支也就被刪除,以保證倉庫中的干凈.
|
# 刪除dev分支 $ git branch -d dev # 如果dev分支還有未提交的內(nèi)容,為了保證你的數(shù)據(jù)安全git默認(rèn)是不允許刪除,可以使用`-D`強(qiáng)制刪除 $ git branch -D dev |
分支管理
git branch 命令不只是可以創(chuàng)建于刪除分支. 如果不添加任何參數(shù), 那么會(huì)得到所有分支的一個(gè)列表
|
$ git branch # 其中一個(gè)分支前面的*代表,目前檢出的分支就是HEAD指針?biāo)赶虻姆种?/div> # 追加-v參數(shù) 可以展示每一個(gè)分支最后一次提交 $ git branch -v # --merged:查看那些分支已經(jīng)合并到當(dāng)前分支 $ git branch --merged # 一般這個(gè)列表展示的除了*號的其他分支, 都可以刪除 # --no-merged:查看所有包含未合并工作的分支 $ git branch --no-merged |
變基
和合并merge 相似的效果都是合并分支, 但是使用變基rebase 可以讓提交歷史變得更簡潔. 如下
圖片1是merge 合并效果, 圖片2是rebase 合并效果. 明顯變基會(huì)讓提交歷史看起來更加干凈. 使用如下:
|
# rebase [需要移動(dòng)變基底的分支] $ git rebase master experiment # 此時(shí)目標(biāo)分支后面會(huì)追加另一個(gè)分支的提交. 此時(shí)只需要切換到master分支,合并分支即可. $ git checkout master $ git merge experiment |
rebase 原理就是, 從目標(biāo)分支和要變基的分支向上查找出共同祖先節(jié)點(diǎn)就是c2 , 然后把要變基的分支到c2 節(jié)點(diǎn)的所有提交,提取出相應(yīng)的修改生成一個(gè)副本, 并追加到目標(biāo)分創(chuàng)建相對應(yīng)的提交. 此時(shí)變基的分支指向目標(biāo)分支master 的后面某一次提交. 此時(shí)只要使用修改master 指向指針使用merge 即可.
遠(yuǎn)程分支
|
# 獲得遠(yuǎn)程的倉庫列表 $ git ls-remote origin # 如果想獲得更多的信息 $ git remote show origin # 查看遠(yuǎn)程分支和本地分支 $ git branch -a |
拉取遠(yuǎn)程分支
假設(shè)遠(yuǎn)程如果有一個(gè)dev 分支, 你使用fetch 進(jìn)行抓取. 這個(gè)時(shí)候, 本地不會(huì)自動(dòng)生成一個(gè)可編輯的副本, 換句話說就是這種情況下, 不會(huì)有一個(gè)新的dev 本地分支, 只有一個(gè)不可以修改的origin/dev 指針. 這個(gè)時(shí)候可以運(yùn)行git merge origin/dev 命令, 將這些遠(yuǎn)程dev分支的工作合并到當(dāng)前分支. 如果想要在自己本地的dev分支上工作, 可以將其建立在遠(yuǎn)程分支之上.
|
$ git checkout -b dev origin/dev |
創(chuàng)建遠(yuǎn)程分支
如果你的本地有一個(gè)新建的dev 分支, 并且你進(jìn)行了提交, 此時(shí)你想把這個(gè)分支也提交到遠(yuǎn)程的dev 分支, 但是遠(yuǎn)程還沒有創(chuàng)建dev , 這個(gè)時(shí)候可以使用如下命令: git push
刪除遠(yuǎn)程分支
|
# 刪除遠(yuǎn)程dev分支 $ git push origin --delete dev |
跟蹤分支
從一個(gè)遠(yuǎn)程跟蹤分支檢出一個(gè)本地分支會(huì)自動(dòng)創(chuàng)建一個(gè)叫做 跟蹤分支 (有時(shí)候也叫做 “上游分支”)。 跟蹤分支是與遠(yuǎn)程分支有直接關(guān)系的本地分支。 如果在一個(gè)跟蹤分支上輸入git pull ,Git 能自動(dòng)地識別去哪個(gè)服務(wù)器上抓取、合并到哪個(gè)分支。
當(dāng)克隆一個(gè)倉庫時(shí),它通常會(huì)自動(dòng)地創(chuàng)建一個(gè)跟蹤 origin/master 的 master 分支。 然而,如果你愿意的話可以設(shè)置其他的跟蹤分支 – 其他遠(yuǎn)程倉庫上的跟蹤分支,或者不跟蹤 master 分支。 最簡單的就是之前看到的例子,運(yùn)行 git checkout -b [branch] [remotename]/[branch] 。 這是一個(gè)十分常用的操作所以 Git 提供了 --track 快捷方式:
|
$ git checkout --track origin/dev # 如果想要自定義本地分支名字 $ git checkout -b 任意分支名字 origin/dev |
設(shè)置已有的本地分支跟蹤一個(gè)剛剛拉取下來的遠(yuǎn)程分支,或者想要修改正在跟蹤的上游分支,你可以在任意時(shí)間使用 -u 或 –set-upstream-to 選項(xiàng)運(yùn)行 git branch 來顯式地設(shè)置。
|
# 設(shè)置HEAD指向的分支的上游為遠(yuǎn)程dev分支 $ git branch -u origin/dev |
查看設(shè)置的所有跟蹤分支
遠(yuǎn)程倉庫操作
克隆倉庫
|
$ git clone # 如果你想創(chuàng)建自己的倉庫名, 就是本地根文件夾的名稱, 那么可以如下追加名稱 $ git clone [dirName] |
查看遠(yuǎn)程倉庫
|
# 默認(rèn)查看遠(yuǎn)程倉庫的方式 $ git remote # 查看遠(yuǎn)程倉庫的讀寫權(quán)限. 如果可以看到(push)說明提交的推送 $ git remote -v |
如果需要查看某一個(gè)倉庫更多的信息時(shí), 使用git remote show ...
添加遠(yuǎn)程倉庫
|
# 格式: git remote add [shortName] 同時(shí)可以指定一個(gè)倉庫的引用名稱,例如 $ git remote add rp git@github.com:suzeyu1992/GitOperateDemo.git # 此時(shí)你想對新加的遠(yuǎn)程進(jìn)行拉取動(dòng)作, 只需要使用之前的引用名稱就可以 $ git fetch rp |
遠(yuǎn)程倉庫的拉取推送
拉取
大家常用的可能是git pull 這個(gè)指令. 這個(gè)指令的通常會(huì)從服務(wù)器上抓取數(shù)據(jù)自動(dòng)嘗試合并到當(dāng)前所在分支.
而我們可以也可以利用git fetch 進(jìn)行本地分支所追蹤的遠(yuǎn)程分支沒有提交. 然后我們可以手動(dòng)的進(jìn)行合并.
推送
git push [remote-name] [branch-name] 例如:
只有當(dāng)對服務(wù)器有寫入權(quán)限, 并且之前沒有人提交, 這條命令才會(huì)生效.
上面的這兩個(gè)推送也好拉取也好. 如果所在分支設(shè)置了遠(yuǎn)程服務(wù)器分支的追蹤, 那么可以省略掉后面的倉庫名和分支名. 如果沒有設(shè)置那么必須顯示的指定.
遠(yuǎn)程倉庫移除重命名
對遠(yuǎn)程倉庫的名稱進(jìn)行修改
|
$ git remote rename oldName newName |
想要移除一個(gè)遠(yuǎn)程倉庫,例如服務(wù)器搬走了,不再使用一個(gè)特定鏡像,或者一個(gè)貢獻(xiàn)者不再貢獻(xiàn)
原文鏈接https://github.com/suzeyu1992/GitOperateDemo
|