Git
git init
在當(dāng)前目錄下創(chuàng)建新的空倉庫路星。git clone
$ git clone <path-to-repository-to-clone>
創(chuàng)建一個(gè)與現(xiàn)有倉庫完全相同的副本。git status
顯示倉庫的當(dāng)前狀態(tài)评腺。git log 顯示倉庫commit信息
git log --oneline 簡略顯示信息
git log --stat 顯示修改信息摘要
git log -p 顯示修改的詳細(xì)信息git show
僅顯示一個(gè)commitgit add
$ git add <file1> <file2> … <fileN>
將文件從工作目錄移到暫存區(qū)git commit
取出暫存區(qū)的文件并保存到倉庫中git diff
查看已經(jīng)執(zhí)行但是尚未 commit 的更改.gitignore 文件
告訴 git 不應(yīng)跟蹤的文件帘瞭。該文件應(yīng)該放在 .git 目錄所在的目錄git tag
$ git tag -a beta
標(biāo)記特定的 commit 。當(dāng)添加新的 commit 時(shí)蒿讥,標(biāo)簽不會移動蝶念。git branch 管理 git 中的分支,列出所有分支
git branch footer-fix 5bfe5e7 創(chuàng)建新的"footer-fix"分支
git branch -d footer-fix 刪除"footer-fix"分支git checkout 切換分支
git checkout -b richards-branch-for-awesome-changes 創(chuàng)建新分支 -b選項(xiàng)git log --oneline --graph --all
查看所有分支git merge
$ git merge <name-of-branch-to-merge-in>
合并 git 分支合并沖突指示符解釋
編輯器具有以下合并沖突指示符:
"<<<<<<< HEAD" 此行下方的所有內(nèi)容(直到下個(gè)指示符)顯示了當(dāng)前分支上的行
"||||||| merged common ancestors" 此行下方的所有內(nèi)容(直到下個(gè)指示符)顯示了原始行的內(nèi)容
"=======" 表示原始行內(nèi)容的結(jié)束位置芋绸,之后的所有行(直到下個(gè)指示符)是被合并的當(dāng)前分支上的行的內(nèi)容
">>>>>>> heading-update" 是要被合并的分支上的行結(jié)束指示符git commit --amend 向 commit 中添加忘記的文件
添加忘記包含的文件(或文件更改)媒殉。假設(shè)你更新了整個(gè)網(wǎng)站的導(dǎo)航鏈接顏色。commit 了該更改摔敛,并以為完事了廷蓉。但是后來發(fā)現(xiàn)深藏在頁面上的一個(gè)特殊導(dǎo)航鏈接沒有新的顏色。你可以執(zhí)行新的 commit 并更新該鏈接的顏色马昙,但是這樣就會出現(xiàn)兩個(gè) commit 執(zhí)行完全相同的任務(wù)(更改鏈接顏色)桃犬。
相反,你可以修改最后一個(gè) commit(更新所有其他鏈接顏色的 commit)以包含這個(gè)忘記的鏈接行楞。要包含忘記的鏈接攒暇,只需:編輯文件、保存文件子房、暫存文件形用、運(yùn)行 git commit --amend。
你對必要的 CSS 和/或 HTML 文件作出了更改证杭,以便修正被遺忘的鏈接樣式田度,然后保存所有被修改的文件,并使用 git add 暫存所有被修改的文件(就像要提交新的 commit 那樣G椤)每币,但是你可以運(yùn)行 git commit --amend 來更新最近的 commit,而不是創(chuàng)建新的 commit琢歇。git revert
$ git revert <SHA-of-commit-to-revert>
還原之前創(chuàng)建的 commit兰怠,通常會用到祖先引用來指代之前的 commit,將 HEAD 和當(dāng)前分支指針移到引用的 commit李茫。
--hard 選項(xiàng)清除 commit
--soft 選項(xiàng)將 commit 的更改移至?xí)捍鎱^(qū)
--mixed 選項(xiàng)取消暫存已被 commit 的更改commit索引
你已經(jīng)知道可以使用 SHA揭保、標(biāo)簽、分支和特殊的 HEAD 指針引用 commit魄宏。有時(shí)候這些并不足夠秸侣,你可能需要引用相對于另一個(gè) commit 的 commit。例如,有時(shí)候你需要告訴 git 調(diào)用當(dāng)前 commit 的前一個(gè) commit味榛,或者是前兩個(gè) commit椭坚。我們可以使用特殊的“祖先引用”字符來告訴 git 這些相對引用。這些字符為:
^ – 表示父 commit
~ – 表示第一個(gè)父 commit
我們可以通過以下方式引用之前的 commit:
父 commit – 以下內(nèi)容表示當(dāng)前 commit 的父 commit
HEAD^
HEAD~
HEAD~1
祖父 commit – 以下內(nèi)容表示當(dāng)前 commit 的祖父 commit
HEAD^^
HEAD~2
曾祖父 commit – 以下內(nèi)容表示當(dāng)前 commit 的曾祖父 commit
HEAD^^^
HEAD~3
^ 和 ~ 的區(qū)別主要體現(xiàn)在通過合并而創(chuàng)建的 commit 中搏色。合并 commit 具有兩個(gè)父級善茎。對于合并 commit,^ 引用用來表示第一個(gè)父 commit频轿,而 ^2 表示第二個(gè)父 commit垂涯。第一個(gè)父 commit 是當(dāng)你運(yùn)行 git merge 時(shí)所處的分支,而第二個(gè)父 commit 是被合并的分支航邢。
Github
git remote
$ git remote add repo-on-GitHub URL
連接到多個(gè)不同的遠(yuǎn)程倉庫耕赘。簡寫名是用于指代遠(yuǎn)程倉庫位置的名稱。通常該位置為 URL膳殷,但也可能是同一臺計(jì)算機(jī)上的文件路徑操骡。
git remote add 添加到新的遠(yuǎn)程倉庫的連接。
git remote -v 查看遠(yuǎn)程倉庫與連接之間的詳細(xì)信息赚窃。git push
$ git push origin master
從本地倉庫向遠(yuǎn)程倉庫推送 commit当娱,包括倉庫名和分支名 。git pull
$ git pull origin master
在本地倉庫拉取遠(yuǎn)程倉庫更改考榨。
在運(yùn)行 git pull 時(shí),會發(fā)生以下活動:
遠(yuǎn)程分支上的 commit 會被復(fù)制到本地倉庫
本地跟蹤分支(origin/master)移到指向最新的 commit
本地跟蹤分支(origin/master)合并到本地分支(master)git fetch
$ git fetch origin master
獲取遠(yuǎn)程更改鹦倚,檢索 commit 和移動跟蹤分支河质。它不會將本地分支與跟蹤分支合并。git shortlog
按作者對 commit 分組震叙,顯示按字母順序排序的人名列表掀鹅,以及他們對應(yīng)的提交說明。
$ git shortlog -s -n
如果我們只想看到每個(gè)開發(fā)者的 commit 數(shù)量媒楼,我們可以添加幾個(gè)選項(xiàng):用 -s 僅顯示 commit 的數(shù)量(而不是每個(gè) commit 的消息)乐尊,以及用 -n 來按數(shù)量排序(而不是按作者姓名的字母順序)。git log --author="Richard Kalehoff" 使用 --author 選項(xiàng)篩選 commit
git log --grep="border radius issue in Safari" 使用 --grep 選項(xiàng)篩選 commit
Github 項(xiàng)目合作
合作規(guī)范
- 在開始任何工作之前划址,確保閱讀項(xiàng)目的 CONTRIBUTING.md 文件扔嵌。
- 接下來,查看項(xiàng)目的 GitHub 問題
- 查看現(xiàn)有的問題夺颤,看是否有哪些內(nèi)容類似于你想貢獻(xiàn)的更改
- 如有必要痢缎,創(chuàng)建一個(gè)新的 Issue
- 與項(xiàng)目維護(hù)者交流你想要做出的更改
- 當(dāng)開始開發(fā)后,將所有工作 commit 到特性分支上世澜;
不要在主分支上工作独旷;
確保給特性分支賦予一個(gè)清晰、描述性的名稱; - 編寫 commit 的一般最佳實(shí)踐嵌洼;
頻繁少量 commit案疲;
使用清晰、具有描述性的提交說明麻养;
必要情況下褐啡,更新 README 文件。
申請推送 Pull Request
Pull Request 是讓源倉庫拉取你的 commit回溺,并融合在其項(xiàng)目中的請求春贸。要創(chuàng)建 Pull Request,你需要完成一些操作:
- 你必須 fork 源倉庫
- 將你的 fork 克隆到你的計(jì)算機(jī)
- 進(jìn)行一些 commit(最好是在特性分支上R抛瘛)
- 將 commit 推送回你的 fork
- 創(chuàng)建一個(gè)新的 Pull Request萍恕,并選擇包含你的新 commit 的分支
壓制commit
git rebase 命令可以用來做很多事情。
交互式 rebase $ git rebase -i <base>
$ git rebase -i HEAD~3
交互式地將 commit 變基到我們當(dāng)前所在的 commit 向前三個(gè)的 commit
在 commit 的交互式列表中车要,所有 commit 都以 pick 開頭允粤,但你可以使用其他命令(reword、edit翼岁、squash类垫、fixup、exec 和 drop)進(jìn)行變換琅坡。
建議在變基之前創(chuàng)建一個(gè)備份(backup)分支悉患,這樣便能很容易返回到之前的狀態(tài)。如果你對變基的結(jié)果滿意榆俺,則可以刪除 backup 分支售躁!
rebase 命令
- 使用 p 或 pick – 使 commit 保持原樣
- 使用 r 或 reword – 保留 commit 的內(nèi)容,但修改 commit 說明
- 使用 e 或 edit – 保留 commit 的內(nèi)容茴晋,但先不要執(zhí)行 commit陪捷,以便:
添加新內(nèi)容或文件
刪除內(nèi)容或文件
修改即將 commit 的內(nèi)容 - 使用 s 或 squash – 將此 commit 的更改結(jié)合到之前的 commit 中(列表中位于其上面的 commit )
- 使用 f 或 fixup – 將此 commit 的更改結(jié)合到前一個(gè) commit 中,但刪除提交說明
- 使用 x 或 exec – 運(yùn)行 shell 命令
- 使用 d 或 drop – 刪除 commit
何時(shí)變基
git rebase 命令非常強(qiáng)大诺擅。它可以幫助你編輯提交說明市袖、重新排序 commit、合并 commit 等烁涌,真的是一款非常強(qiáng)大的工具〔缘現(xiàn)在的問題是"應(yīng)該何時(shí)進(jìn)行變基?"撮执。
每當(dāng)你對 commit 進(jìn)行變基驰怎,Git 將為每個(gè) commit 創(chuàng)建一個(gè)新的 SHA!這有很大的影響二打。對于 Git县忌,SHA 為 commit 的標(biāo)識符掂榔,因此不同的標(biāo)識符代表著不同的 commit,無論內(nèi)容是否發(fā)生了變化症杏。
如果你已推送了你想進(jìn)行變基的 commit装获,則不應(yīng)變基。如果你在與其他開發(fā)者協(xié)作厉颤,那么他們可能已經(jīng)在使用你推送的 commit穴豫。如果你隨后使用 git rebase 來進(jìn)行更改,并強(qiáng)行推送 commit逼友,則其他開發(fā)者現(xiàn)在將無法與遠(yuǎn)程倉庫同步精肃。他們需要對自己的 Git 倉庫進(jìn)行一些復(fù)雜的手術(shù),使它們的倉庫回到工作狀態(tài)……甚至可能連這一點(diǎn)都做不了帜乞;他們可能得拋棄之前的所有工作司抱,使用你新變基過且強(qiáng)制推送的 commit 重新開始。
通用術(shù)語
版本控制系統(tǒng) / 源代碼管理器
版本控制系統(tǒng)(簡稱 VCS)是一個(gè)管理源代碼不同版本的工具黎烈。源代碼管理器(簡稱 SCM)是版本控制系統(tǒng)的另一個(gè)名稱习柠。
Git 是一個(gè) SCM(因此也是 VCS!)照棋。Git 網(wǎng)站的 URL 是 https://git-scm.com/ (注意它的域名中直接包含“SCM”W世!)。
提交(Commit)
Git 將數(shù)據(jù)看做微型文件系統(tǒng)的一組快照烈炭。每次 commit(在 Git 中保持項(xiàng)目狀態(tài))溶锭,它都對文件當(dāng)時(shí)的狀況拍照,并存儲對該快照的引用符隙。你可以將其看做游戲中的保存點(diǎn)暖途,它會保存項(xiàng)目的文件和關(guān)于文件的所有信息。
你在 Git 中的所有操作都是幫助你進(jìn)行 commit膏执,因此 commit 是 Git 中的基本單位。
倉庫(Repository / repo)
倉庫是一個(gè)包含項(xiàng)目內(nèi)容以及幾個(gè)文件(在 Mac OS X 上默認(rèn)地處于隱藏狀態(tài))的目錄露久,用來與 Git 進(jìn)行通信更米。倉庫可以存儲在本地,或作為遠(yuǎn)程副本存儲在其他計(jì)算機(jī)上毫痕。倉庫是由 commit 構(gòu)成的征峦。
工作目錄 / 工作區(qū)(Working Directory)
工作目錄是你在計(jì)算機(jī)的文件系統(tǒng)中看到的文件。當(dāng)你在代碼編輯器中打開項(xiàng)目文件時(shí)消请,你是在工作目錄中處理文件栏笆。
與這些文件形成對比的是保持在倉庫中(在 commit 中!)的文件臊泰。
在使用 Git 時(shí)蛉加,工作目錄與命令行工具的 current working directory (當(dāng)前工作目錄)不一樣,后者是 shell 當(dāng)前正在查看的目錄。
檢出(Checkout)
檢出是指將倉庫中的內(nèi)容復(fù)制到工作目錄下针饥。
暫存區(qū) / 暫存索引 / 索引(Staging Area / Staging Index / Index)
Git 目錄下的一個(gè)文件厂抽,存儲的是即將進(jìn)入下個(gè) commit 內(nèi)容的信息《⊙郏可以將暫存區(qū)看做準(zhǔn)備工作臺筷凤,Git 將在此區(qū)域獲取下個(gè) commit。暫存索引中的文件是準(zhǔn)備添加到倉庫中的文件苞七。
SHA
SHA 是每個(gè) commit 的 ID 編號藐守。以下是 commit 的 SHA 示例:e2adf8ae3e2e4ed40add75cc44cf9d0a869afeb6
。
它是一個(gè)長 40 個(gè)字符的字符串(由 0–9 和 a–f 組成)蹂风,并根據(jù) Git 中的文件或目錄結(jié)構(gòu)的內(nèi)容計(jì)算得出卢厂。SHA 的全稱是"Secure Hash Algorithm"(安全哈希算法)。如果你想了解哈希算法硫眨,請參閱我們的計(jì)算機(jī)科學(xué)入門課程足淆。
分支(Branch)
分支是從主開發(fā)流程中分支出來的新的開發(fā)流程。這種分支開發(fā)流程可以在不更改主流程的情況下繼續(xù)延伸下去礁阁。
回到之前關(guān)于游戲保存點(diǎn)的示例巧号,你可以將分支看做在游戲中設(shè)立保存點(diǎn)后,嘗試一個(gè)有風(fēng)險(xiǎn)的招式姥闭。如果有風(fēng)險(xiǎn)的招式不奏效丹鸿,則回到保存的位置。令分支非常強(qiáng)大的關(guān)鍵之處是你可以在一個(gè)分支上設(shè)定保存點(diǎn)棚品,然后切換到另一個(gè)分支并繼續(xù)設(shè)定保存點(diǎn)靠欢。
了解日志內(nèi)容
如果你不習(xí)慣在命令行上使用分頁器,那么 less(英) 用起來會比較奇怪铜跑。以下是一些實(shí)用技巧:
要向下滾動门怪,按下
j
或↓
一次向下移動一行d
按照一半的屏幕幅面移動f
按照整個(gè)屏幕幅面移動要 向上滾動,按下
k
或↑
一次向上移動一行u
按照一半的屏幕幅面移動b
按照整個(gè)屏幕幅面移動按下
q
可以退出日志(返回普通的命令提示符)
良好的提交說明
我們來思考一個(gè)問題:
如何編寫良好的提交說明锅纺?為何要編寫好的提交說明掷空?
問的好!花點(diǎn)時(shí)間編寫良好的提交說明囤锉,再怎么強(qiáng)調(diào)這一點(diǎn)都不為過坦弟。
何為好的提交說明呢?問的好官地,很多人發(fā)表過關(guān)于這一問題的文章酿傍,比如: 如何編寫 Git Commit Message - 英|譯文 、Commit message 和 Change log 編寫指南驱入。在編寫好的提交說明時(shí)赤炒,需要注意以下幾個(gè)事項(xiàng):
建議
消息篇幅簡短(少于 60 個(gè)字符)
解釋提交的作用(不是如何更改或?yàn)楹胃模氯析。?/p>
禁忌
請勿解釋為何做出了這些更改(下文會深入講解這一點(diǎn))
請勿解釋如何進(jìn)行了更改(這是
git log -p
的目的=缁 )請勿使用單詞"and"
如果你必須使用 "and"插爹,則你的提交說明可能進(jìn)行了太多的更改闰非,將這些更改拆分為獨(dú)立的 commit
例如 "make the background color pink and increase the size of the sidebar"
在編寫提交說明時(shí)尔许,我喜歡用以下短語造句:"This commit will…"启上。你可以補(bǔ)充完整該句子并作為提交說明使用碌尔。
通配符速成課程
假設(shè)你向項(xiàng)目中添加了 50 個(gè)圖片捏萍,但是希望 git 忽略所有這些圖片系冗。這樣的話旷余,是否需要將每個(gè)文件名都列在 .gitignore
文件中呢绢记?當(dāng)然不用了,要不然太可怕了正卧!相反蠢熄,你可以采用一個(gè)叫做 通配符(英 的概念。
通配符允許你使用特殊的字符來表示某些格式/字符炉旷。在 .gitignore
文件中签孔,你可以使用:
- 空白行作為空格
-
#
- 將行標(biāo)記為注釋 -
*
- 與 0 個(gè)或多個(gè)字符匹配 -
?
- 與 1 個(gè)字符匹配 -
[abc]
- 與 a、b 或 c 匹配 -
**
- 與嵌套目錄匹配 -a/**/z
與以下項(xiàng)匹配- a/z
- a/b/z
- a/b/c/z
因此如果所有 50 個(gè)圖片都是 JPEG 圖片窘行,并且位于"samples"文件夾中饥追,那么我們可以向 .gitignore
中添加以下行,使 git 忽略所有這 50 個(gè)圖片罐盔。
samples/*.jpg