[TOC]
前言
剛剛開始使用Git的版本控制時,我根本不確定我付出那么多時間是不是會得到回報,Branch、Stage、Stash、Commit、pull、push、origin這些Git名詞對我來說都非常陌生。
今天的我已不能想象開發生活沒有Git會變成什么樣。
Git不僅提供了非常非常非常需要的版本控制功能,還讓我變成一個優秀的程序員。
如何學習Git
最快速的學習就是命令
# 展示顯示幫助的命令
git --help
# 顯示 拉取操作的命令用法
git help pull
終端輸入后,都是直接開啟幫助文檔,當然都是英文,請自備詞典
學習書籍
看不懂英文,沒事小黃書一本
感謝開源社區 GitHub progit2
Git 視頻教程
Git版本控制視頻教程 共有5個視頻,因為軟件教學視頻的更新非常快,而且有實效性,一般不會存留太久,請尊重作者版權,拒絕侵權行為
Git換行符規約
必須使用 Unix 風格的行編碼
缺省涵蓋 BSD/Solaris/Linux/OSX 的用戶,也就是 LF 換行風格,Windows 用戶要格外小心,不然出現莫名其妙的沖突。
如果你使用 Git ,你請一定加入下面這個全局配置,來保護你的項目不被 Windows 的行編碼侵入導致項目故障:
# Mac 請設置為
git config --global core.autocrlf input
# Windows 請設置為
git config --global core.autocrlf true
從簡單的工作流開始
Git的最核心,也是最根本的用法就是工作流,不需要任何高級功能,要的就是簡單粗暴,堅守原則的git工作流,在任何大型項目中都適用,svn被淘汰的根本原因就是不能適應工作流。
而工作流是基于Git的分區來工作的,Git在使用的過程中會沉淀很多 commit 和少量的tag,對外展現一個 README,實際開發中,小型或者個人項目使用基礎工作流,大型項目使用模板工作流。
Git的分區概念
區域名稱 | 位置 | 用途 |
---|---|---|
工作區(working copy) | 就是你當前PC看到的目錄 | 日常文本操作或者查看 |
版本庫(version) | 工作區里的隱藏目錄 .git | 維持本地git各種管理,分支管理,暫存管理,備份管理等等,不用刻意在意它 |
暫存區(Stage) | 版本庫里的東西 | git add命令添加到的就是stage分區,commit就是將暫存區的目標內容提交到當前本地分支 |
遠程區(origin) | 服務端的代碼 | 有時候也叫 服務庫,作為開發組的同步基準,不要和部署代碼的遠程服務器混淆了,部署到服務器的其實也是一個服務器上的本地工作分支 |
基本工作流
用git干活就是工作流方式,簡單直接粗暴
Git的工作日常就是,重度關心自己的本地一個分支,不斷提交做筆記,一定確認后push(推送)
check -> pull -> add -> commit -> pull ---------------> push -> check
| |
| |
> merge -> commit -->
這是一個從檢查確認開始到檢查確認的循環
Git使用原則
不到萬不得已,不要跨分支提交,除非你不暈多維空間,反正我是暈的
打開工程,拉取一次, 切換本地倉庫分支,拉取一次
不要做任何備份(stash),你會在本地倉庫建立幾何倍數的本地倉庫,直到自己無法維護為止
不建議留任何未提交文件就去拉取,Fetch雖好,不要貪拉
不要把系統臨時文件,開發工具配置文件,項目配置文件,執行結果文件,編譯過程文件,壓縮優化文件,日志文件等等,反正是大部分開發者人一眼看不懂內容的文件,或者肯定會和隊友沖突的文件,扔到git遠程區上去,這樣會制造百分百麻煩
拉取不成功,解決沖突,提交不成功,解決沖突,解決不了沖突,請聯系隊友
沖突解決后,別閑著,要提交,要提交,要提交!
分支合并前,或者提交合并前,注意誰指向誰,工作流執行時幾乎都是單向合并
推送前,一定確認還有沒有文件沒有提交,然后才是,看清楚推送的是誰到誰
使用混合命令偷懶是對的,前提是遵守基礎工作流,不然你得修復自己制造的錯誤
服務器上的部署分支,嚴禁做任何提交和修改,這是在制造麻煩,服務器上的部署倉庫只需要拉取發布分支的提交或者拉取發布的Tag就行
除了部署服務器的pull的默認策略為rebase外,請默認pull的策略為merge
永遠別怕犯錯誤,因為git是每個參與者都是備份,git天生帶有非常強悍的修復能力,git是作死都不會死的,除非你不遵守上面的所有原則,這么多原則都不準守的難度確實很大
提交commit和標簽tag
git是一個重度commit的使用方式,故會產生極多的commit,時間一長就不好找,tag就是用于管理查詢的
tag用于標識發布,或者重度bug,或者倉庫遷移,tag和commit可以跨分支查詢
ignore的重要性
ignore基礎用法是防止沒必要的提交的,當然活用的話會非常適合做團隊開發,使用合理的ignore來配置團隊開發依賴,維護ignore模板是一個開發者的基本工作。
Markdown的實用性
git倉庫幾乎都是用Markdown來寫 README的,怎么寫Markdown得單獨開章節了。
當然README也有點規矩,README的寫法見 另開貼的 README.md 規范
工作流與工作流模板推薦
工作流的詳細介紹請參閱 深入理解學習Git工作流 感謝博主對于開源的支持。
作流模板推薦
設計者的Git工作流
Markus Prinz的Git工作流
Yehuda Katz的普通Git工作流
Agile團隊的Git工作流
開始用git去作死吧
不要因為覺得Git什么都是命令行,感覺很復雜,學習壓力很大,還TMD的全是英文看不懂,你完全可以從今天開始使用Git,去git建立一個git倉庫,然后愉快的作死去!
不要再害怕犯錯誤
Git最出色的一點是:使用Git幾乎是100%要出錯誤
以下幾點git的特性讓你不再害怕
Git基本上不刪除數據。即使是那些看起來是刪除數據的操作,實際上是為了讓你更快的撤銷刪除,而在向系統添加數據
Git基本可以撤銷所有操作。鼓勵你更多的實驗和探索你的想法,因為這就是使用版本控制系統系統的最主要的好處之一
你團隊的每一個成員都在他/她的計算機中有各自的副本。本質上這更像是整個版本控制項目中的冗余備份(包括包括整個歷史紀錄),你捅了大婁子而且還沒辦法還原這種情況是極其少見的
理解分支
Git基本分支和合并方法
分支樹是一個Git分支和合并的簡短介紹
Git分支是一個繪圖過程,圖形越好識別,說明工作流越適合這個團隊
一個成熟的Git分支模型是大家無意中,用工作流創建的
暫存區解惑
Stage(暫存區) 不是用來做備份,不是用來做備份,不是用來做備份,很重要,需要說三次,用上Git后,你的隊友,服務端都是你的完全備份,而萬惡的 Stash 才是備份。
--stat參數可以看到每次提交的文件變更統計
# 顯示被修改文件的修改統計信息
git log --stat
origin working stash 是你每次用git的時候,必然看到的3個區 遠程區 工作區 暫存區 (其實是有備份區,但是強調了不要有備份區出來)
查看提交暫存區和版本庫中文件的差異
git diff --cached #or git diff --staged
當對工作區中被修改的文件執行git add時,暫存區中的目錄將被更新,同時工作區被修改的文件內容會被寫入到對象庫中的一個新的對象中,新對象的ID被記錄在暫存區的文件索引中。
git commit時,暫存區的目錄樹會寫到版本庫(對象庫)中,master分支會做相應更新,即master最新指向的目錄樹就是提交時原暫存區的目錄樹
git reset HEAD時,暫存區的目錄樹會被重寫,會被master分支指向的目錄樹替換,但是工作區不受影響
git rm --cashed <file>或git checkout -- <file>時,會用暫存區全部的文件或指定的文件替換工作區的文件!!
git checkout HEAD或git checkout HEAD <file>會用HEAD指向的master分支中的全部或相應文件替換暫存區和工作區中的文件。當進行提交時,實際上是將暫存區的內容提交到版本庫中
請使用Git圖形界面
對于程序員來說
不會用終端命令的程序員是沒有獸性的,這種碼農生存困難,衣食堪憂
不過還有一句話
沒有界面或者一鍵安裝的軟件或者系統,都是在耍流氓
所以,請在日常開發中,多使用圖形界面,并混合git命令來不斷提高自己
管理工具-Git 桌面版
多種倉庫類型支持的 SourceTree
安利一下 SourceTree 支持 git 和 svn hg等
SourceTree還有一個好處就是可以中文,提供各種非常人性的快捷方式,還有最重要的,能看到你的每次Git操作的命令內容。
目前最流行的Github 推出的 Github desktop
Github desktop 編程界的圣地亞哥,Github官方客戶端,功能不多,但是沒有蛀牙~
開發工具-Git IDE插件
Eclipse家族
Eclipse 及其衍生的IDE,比如zend,還有各種馬甲的,請使用有嚴重bug的 EGit
(但是在Eclipse生態圈,Egit已經是Bug最少的了),Egit最常見的bug就是暫存區突然出現莫名其妙的文件,文件名各種隨機,文件內容一般奇怪,無法忽略,無法定位,出現一次得整個團隊折騰一次。
當然現在Eclipse已經被替代了,Eclipse生態已經進入死亡期,新的Eclipse已經放棄了老生態,改名叫Eclipse che
建議改用當今時代的IDE,或者 sublime text
或者 Atom
這樣的智能編輯器
非得用Eclipse的話,安裝Egit也很簡單,EGit 的版本繁多,Bug也多,除了原生 Eclipse 通過 Eclipse Market 安裝良好,其他的衍生品IDE,請自行查找對應版本的安裝源。
JetBrains 家族
集成開放環境推薦使用 Jetbrains 家的東西,插件很多,快捷鍵合理一致,響應快速(前提會java優化),默認帶有非常完善的Git插件
Jetbrains的 Git工具沒有嚴重bug,還有很多Git工具插件類似 .ignore
含義非常實用的git ignore管理和內置了各種使用ignore模板,而且人性化很多(用了1年的EGit日常記它小黑本)
Jetbrains 的IDE有
名稱 | 語言 | 用途 | 是否付費 |
---|---|---|---|
IntelliJ | Java | java開發,JetBrains的基礎 | 否 |
Android Studio | Java | Anroid開發,基于IntelliJ,谷歌扶持 | 否 |
WebStorm | Web Javascript CSS | Web H5等等的開發套件 | 是 |
PyCharm | Python Web Javascript | Python開發套件,基于WebStorm | 是 |
RubyMine | Ruby Web Javascript | Ruby開發套件,基于WebStorm | 是 |
PhpStorm | php web | php開發套件,基于WebStorm | 是 |
AppCode | Swift OC | iOS/OS X 開發套件,個人感覺比XCode那個連插件管理都做不好的好太多 | 是 |
CLion | C C++ | C語言的開發套件,目前最智能的C語言IDE(其實是因為其他的不爭氣) | 是 |
OxDBE | database&SQL | 數據庫管理工具 ORACLE MySQL MongoDB SQLite DB2 SYBASE | 是 |
JetBrains幾乎覆蓋了所有的開發環境,JetBrains的快捷鍵統一,界面統一,只有一次的學習成本,如何入門JetBrains,以及深入使用,請等新帖鏈接,因為JetBrains實在太強大而且功能太多了。
富文本編輯器
推薦 Sublime Text 3 的git插件,具體使用另開篇幅
Atom 是由GitHub出品的,肯定帶有git的編輯器,使用參見Atom 編輯器 入門 快捷鍵 插件安利
從 SVN 投奔過來的注意事項
git 和 svn區別
git是分布式版本管理,也就是本地即完整的倉庫,包括所有的提交,分支,標簽等,而且提交,分支等操作都是在本地進行,與遠程倉庫只是相互同步的關系
svn是集中式版本管理,本地只是遠程倉庫的某個鏡像,比如處于某個分支,某個版本,但不保存其他版本信息,提交或者建分支等操作都是要連接遠程倉庫的。
svn 中本地和遠程的關系相當于我們瀏覽器打開網站和該網站的服務器的之間的關系,我們本地只是狀態,而我們要提交修改或切換頁面都是通過與服務交互進行的。
而 git中本地和遠程的關系相當于兩臺服務器之間的關系,兩者都能獨立完成操作,兩者之間需要的只是同步。
使用版本管理工具的最大壞習慣
使用SVN的10個有9.9個喜歡不完全提交,因為懶或者緊急情況什么的,理由有很多,反正就是有提交殘留
提交殘留又稱代碼垃圾,提交殘留導致團隊工作過程中,大家都出現沒完全提交,故大家都會扔代碼垃圾。
代碼垃圾和垃圾代碼是兩個東西,一個是代碼管理的,一個是開發水平的,不可混談
SVN是同步式設計,設計上要求一定同步,所以,我見過的開發團隊只要是SVN管理的代碼,只要開發了一段時間后,代碼都是一團糟,因為這些團隊都在違背SVN的設計--完全同步,所以團隊項目是SVN管理的免不了成為代碼垃圾場,SVN損壞啊,不知道搞了啥東西,各種額外備份啊,各種應對方法都來了,效果就是拆東墻補西墻。
Git其實也怕不提交代碼,制造代碼垃圾
當然Git與SVN不同,很多SVN到Git的玩家,學會了緩存區,本地多分支什么的,以此繼續扔代碼垃圾的職業人生。
開始的使用Git的時候,他們玩得很hi沒出簍子,但很快發現垃圾代碼在影響自己的每一天提交,甚至導致本地工作區和暫存區損壞,他們會覺得Git老是和他們作對,然后就向Git發脾氣,抱怨沒有XXX好用。
任何時候,不要和嚴謹的程序生氣,因為一開始你就輸了。
冷靜下來后,他們開始做完全提交,一步一的改正不好的習慣,最后他們都放棄了制造代碼垃圾。
因為以前SVN是單一服務器,扔垃圾不會臭自己,要臭臭全家,既然大家都臭就都糊涂裝沒事情,但是在Git管理下,扔垃圾代碼都是臭自己,讓那些制造垃圾的收拾自己的爛攤子去。
造成上述的代碼垃圾原因是一個,影響卻是完全不同,建議使用git管理團隊代碼,畢竟不靠譜的隊友什么時候都不會缺少的,git會隔離這些豬隊友,并讓他們惡心自己。
Git tips
常用命令
把一個本地文件夾提交到遠程倉庫
首先需要一個遠程倉庫地址,需要有訪問權限的那種
git init
# first of all you need .gitignore
git add .gitignore
git add --all
git commit -m "init commit"
# you need git address [git or https]
git remote add origin [git address] && git push -u origin master
查詢自己搞了什么幺蛾子
# 查詢當前git本地倉庫存在咩問題
git status
# 查看自己搞了什么飛機
git diff [文件路徑/文件名]
查詢修改
# 顯示被修改文件的修改統計信息
git log --stat
# 逐行顯示歷史
git log --pretty=oneline
# 顯示最近[number]條的修改
git log --stat -[number]
# 顯示具體的修改
git log -p -2
# 顯示我自己的修改
git log --stat --author=[Your name]
# 查看單個文件[file path]最近[times]次修改的記錄
git log --stat -[times] -- [file path]
精準的提交
git commit -m "[commit message]"
提交寫錯了沒事可以這樣做
# 逐行顯示歷史
git log --pretty=oneline
# 針對目標提交
git rebase -i [commit name]
# 或者找出分支名的最近[times]次提交
git rebase -i HEAD~[times]
# 等待一會兒后,會進入 vi 界面然后會出現[times]行的提交 和操作提示
pick: [commit name]
pick: [commit name]
pick: [commit name]
...
# 使用vi編輯操作修改你需要改的那個[commit name],從pick改成edit,然后保存退出查看日志
git log
# 提交正確的message
git commit --amend -m "[message]"
# 最后重置提交一下
git rebase --continue
這個方法也可以用于修改commit的文件,不過不建議這樣做,建立新的提交就行,錯了不丟人,丟人的是知錯不改,還藏著
查看我的提交歷史
# 查看完全歷史
git log
# 逐行顯示歷史
git log --pretty=oneline
快速回退工作區版本
# 工作區回退到上一個版本
git reset --hard HEAD^
# 工作區回退到上上個版本
git reset --hard HEAD^^
# 工作區回退到上第 times 個的版本
git reset --hard HEAD^[times]
# 工作區回退到某個名字[commit] 的版本
git reset --hard [commit]
查看自己歷史干了啥輸入了什么命令
git reflog
撤銷工作區修改
# 撤銷目標文件[filename]的修改
git checkout -- [filename]
刪除工作區文件
# 刪除工作區的[filename]文件
git rm [filename]
找回錯誤刪除的文件
# 刪除錯誤的文件[filename]
git checkout [filename]
git tag 使用
tag 用于版本發布,分支用于開發管理,千萬別使用分支來區分功能,會非常難使用
# 創建輕量標簽
git tag 1.0.0
# 創建附注標簽
git tag -a 1.0.0 -m "1.0.0 msg"
# 顯示標簽
git show
# 切換到標簽
git checkout [tagName]
# 刪除標簽
git tag -d [tagName]
# 給指定的commit打標簽
git tag -a [tagName] [commit]
# 標簽發布
git push origin [tagName]
# 本地所有標簽一次性提交
git push origin –tags