Git應(yīng)該是一個程序員必備的技能癞松,但居然有人不會爽撒。最近在準(zhǔn)備實習(xí),在對自己的技術(shù)進行查漏補缺(女媧補天)响蓉,有不少同學(xué)也跟我一樣硕勿。因此前幾天,一個同學(xué)問我你會Github嗎枫甲?我說會霸次洹!他用敬佩的眼神癡癡地看著我想幻,我淡定的說其實挺簡單的粱栖。
Git作為必備技能,為什么會有人不知道呢脏毯?我想大概這是個工具吧闹究,所以學(xué)校里也不教,大家也就不學(xué)食店。想學(xué)的呢渣淤,網(wǎng)上看了一些教程,又非常的晦澀難懂吉嫩,其實入門還是很簡單的(我也只會一些基本操作价认,目前夠用),于是今天我就翻開我的筆記本自娩,把之前學(xué)習(xí)Git做的一點點筆記分享給大家刻伊。
Git是什么?
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.(官網(wǎng)復(fù)制來的)
Git是一個開源免費的版本控制器椒功,不管是大項目還是小項目捶箱,都可以又快又準(zhǔn)的把你治的服服貼貼。
這是linux之父的一周還是兩周的一個作品动漾,因為Linux內(nèi)核開源后參與的人非常多丁屎,人工的合并代碼很麻煩且容易出錯,當(dāng)時已有的版本控制庫還想跟linux收保護費旱眯,于是就有了Git晨川,具體來歷自己去搜搜吧证九,我就不復(fù)制了。
那么版本控制是什么意思呢共虑?己沛?
為什么我們平時用不到呢癞蚕,因為我們在學(xué)校里寫的代碼依许,一共就一個版本狭园,一般都是獨立完成,項目還很小尘分,寫完以后作用就不大了猜惋。
但是大項目就不一樣了,有許許多多的版本培愁。比如說絕地求生
- 垃圾服務(wù)器天天維護著摔,游戲天天出Bug,就得天天更新定续,所以把歷史版本谍咆,變動記錄下來是有意義的,萬一哪天改完了發(fā)現(xiàn)游戲都進不去了私股,還可以切換到昨天的版本讓玩家玩玩Bug版本摹察。
- 一部分程序員得研究怎么防外掛,一部分要研究怎么出新地圖庇茫,新玩法,那么兩部分人怎么合作呢螃成?旦签?
Git安裝
Linux下:
sudo apt-get install git
Windows下:
安裝之后配置一下個人信息:
git config --global user.name "wuyanzu"
git config --global user.email "xxxx@xx.xxx"
理解三個區(qū)域
理解Git如何工作首先要弄明白Git的三個區(qū)域,相當(dāng)于三個不同的目錄
- 工作目錄
- 暫存區(qū)
- Git倉庫
工作目錄
工作目錄就是我們保存代碼的那個目錄
暫存區(qū)
一個介于工作目錄和Git倉庫之間的目錄寸宏,就當(dāng)臨時倉庫吧
Git倉庫
保存每個版本的倉庫宁炫,每一個版本都完整保存,內(nèi)部有一個HEAD指針
一般的工作流程
在工作區(qū)寫代碼氮凝,修改代碼
將修改的代碼放入暫存區(qū)
將暫存區(qū)的改動提交到Git倉庫
一個完整流程遇到的命令介紹
Git是有圖形操作界面的羔巢,但是一般都學(xué)命令操作,命令操作學(xué)會了圖形自然而然就會了罩阵。
首先我們創(chuàng)建一個目錄竿秆,用于放代碼,并初始化Git倉庫稿壁。
mkdir project_1
cd project_1
git init
# output: 初始化空的 Git 倉庫于/home/chenfeikun/project_1/.git/
git init
的作用是初始化幽钢,告訴Git這個目錄以后要被控制,被記錄傅是,現(xiàn)在目錄里會多出一個.git
文件夾匪燕,是一個隱藏文件,這個文件夾以后會自動記錄各種操作蕾羊,不要動它就行。
然后在目錄里開始創(chuàng)作帽驯,寫了一個README和一個hello.py
chenfeikun@cfk-ubuntu:~/project_1$ ls
hello.py README.md
執(zhí)行g(shù)it status查看文件變動情況
chenfeikun@cfk-ubuntu:~/project_1$ git status
位于分支 master
初始提交
未跟蹤的文件:
(使用 "git add <文件>..." 以包含要提交的內(nèi)容)
README.md
hello.py
提交為空龟再,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
git發(fā)現(xiàn)我們添加了兩個文件,還沒有被追蹤尼变,可以用git add
追蹤利凑。追蹤呢就是讓git一直注意著這個文件,任何改動都會被發(fā)現(xiàn)享甸,git add
就把文件放入我們之前提到的暫存區(qū)截碴。
執(zhí)行g(shù)it add <file_name>或git add *
chenfeikun@cfk-ubuntu:~/project_1$ git add README.md hello.py
這個沒有提示,所以我們可以再用git status
來查看一下現(xiàn)在的狀態(tài)蛉威。
位于分支 master
初始提交
要提交的變更:
(使用 "git rm --cached <文件>..." 以取消暫存)
新文件: README.md
新文件: hello.py
可以看到這兩個文件已經(jīng)提交到暫存區(qū)了日丹,如果突然發(fā)現(xiàn)hello.py需要修改,或者是機密文件不能傳出去蚯嫌,那么可以按提示里的命令取消暫存哲虾,或者修改hello.py后重新執(zhí)行git add
。
一切OK后就需要提交到Git倉庫了择示,提交到這里面就算保存了第一個版本了束凑,后續(xù)的提交就算是新的版本了。
使用git commit -m 'xxx'提交至Git倉庫
chenfeikun@cfk-ubuntu:~/project_1$ git commit -m 'add two new file'
[master (根提交) 7319582] add two new file
2 files changed, 5 insertions(+)
create mode 100644 README.md
create mode 100644 hello.py
-m的作用就是在提交的時候附加一個提交的說明栅盲,這樣以后找歷史版本會方便一點汪诉, xxx就是附加的內(nèi)容。
仔細(xì)看提交之后的輸出谈秫,[]里有一串字符串7319582(不全是數(shù)字)扒寄,這里顯示的其實只是前面的一部分,完整的還很長拟烫。這個字符串是標(biāo)識每一次提交的该编,也就是每一次提交都會生成一個唯一的字符串,在同一個倉庫里這個字符串只會出現(xiàn)一次硕淑。這個字符串可以用于以后切換版本课竣,只需要輸入前面幾位就行,不需要補全置媳。記不住也沒關(guān)系于樟,有命令可以查詢這個唯一標(biāo)識。
回到過去
上面我們介紹了從工作目錄到暫存區(qū)再到Git倉庫的過程拇囊,那么如何反過來呢隔披?
從Git倉庫到暫存區(qū)
git reset --mixed HEAD
git reset --soft HEAD~
git reset --hard HEAD~~
git reset HEAD~3
git reset 7319582(指定版本的唯一標(biāo)識串)
HEAD在Git倉庫中指向的是最新版本,HEAD~是最新版本的上一個版本寂拆,HEAD~~是上兩個版本奢米,但是總不能寫很多個~~~~~~抓韩,所以可以寫成HEAD~N,N就是~的個數(shù)鬓长。
git reset就是把Git倉庫中的版本谒拴,覆蓋暫存區(qū)的版本,甚至覆蓋工作區(qū)的版本(有危險的涉波,你修改的內(nèi)容可能全部丟失)英上。
mixed,soft,hard三個參數(shù)就是決定如何覆蓋的,其中mixed是默認(rèn)選項啤覆,也就是不輸入?yún)?shù)時的選項苍日。
用git reset HEAD~
舉例說明三種參數(shù)各自情況
soft:移動HEAD指針指向上一個版本,暫存區(qū)窗声,工作區(qū)無變化
mixed:移動HEAD指針指向上一個版本相恃,并用HEAD當(dāng)前指向的版本覆蓋暫存區(qū),工作區(qū)域不變(注意這時候使用git status會指出工作區(qū)變化了笨觅,那是因為工作區(qū)與最新的暫存區(qū)不一樣了拦耐,本質(zhì)是暫存區(qū)改變了)
hard:移動HEAD指針指向上一個版本,并用HEAD當(dāng)前指向的版本覆蓋暫存區(qū)和工作區(qū)(危險见剩,工作區(qū)修改會丟失)
查詢版本ID號
每一次提交到Git倉庫都有一串哈希值杀糯,就叫它ID號吧。怎么查詢呢苍苞,有兩個命令git log
和git relog
固翰。
假設(shè)提交了四次,Git倉庫內(nèi)是這樣的:A->B->C->D,HEAD->C羹呵。
因為HEAD指向了倒數(shù)第二次提交的C版本骂际,那么使用git log
只會顯示出C之前的所有提交,使用git reflog
才會把所有的提交都顯示出來担巩。
HEAD指向C: git reset a9a00d
reflog:
chenfeikun@cfk-ubuntu:~/project_1$ git reflog
a9a00d0 HEAD@{0}: reset: moving to a9a00d
d431515 HEAD@{1}: commit: commit D
a9a00d0 HEAD@{2}: commit: commit C
6890baf HEAD@{3}: commit: commit B
7319582 HEAD@{4}: commit (initial): add two new file
log:
chenfeikun@cfk-ubuntu:~/project_1$ git log
commit a9a00d07fb3a07bb880d7c9835dcfcd2c15ade04
Author: cfk1996 <297770449@qq.com>
Date: Fri Mar 2 16:17:11 2018 +0800
commit C
commit 6890baf18c283c60e9f29df4be7948fc248e91f0
Author: cfk1996 <297770449@qq.com>
Date: Fri Mar 2 16:16:52 2018 +0800
commit B
commit 731958281a1d63b552f90367dc8d68c1a17c632d
Author: cfk1996 <297770449@qq.com>
Date: Fri Mar 2 15:42:48 2018 +0800
add two new file
從暫存區(qū)到工作區(qū)
上面一小節(jié)的命令以及可以覆蓋工作區(qū)了方援,但是那些都是Git倉庫中的版本没炒。有時候我們git add
后涛癌,在還沒有git commit
之前,又在工作目錄中修改了代碼送火,覺得改的不好拳话,想切換到?jīng)]改之前的樣貌,就可以把暫存區(qū)的內(nèi)容復(fù)制到工作區(qū)种吸。
git checkout --<filename>
總結(jié)一下三個目錄
- 工作目錄--
git add
-->暫存區(qū)--git commit
-->Git倉庫 - 工作目錄<--
git checkout
--暫存區(qū)<--git reset
--Git倉庫
git分支
Git另外一個重要的功能就是分支了弃衍,分支可以多人合作開發(fā)以及開發(fā)新功能的需求。我目前沒怎么用到過坚俗,所以就只是簡單的介紹一下镜盯,主要還是搞懂三個分區(qū)的概念岸裙,其次就是弄懂Git倉庫里各個版本是用指針連在一起的。所以分支就是在Git倉庫中某個版本A復(fù)制一份A’速缆,然后創(chuàng)建一個A->A'的指針降允,就可以互不干擾的在兩處地發(fā)進行開發(fā)。
創(chuàng)建分支
git branch branch-name # 無提示
切換分支
git checkout branch-name
這個命令進行的操作就是將HEAD指針指向分支艺糜,且覆蓋工作區(qū)文件剧董。(切回原來的分支,還會覆蓋一次破停,所以不丟失)
合并分支
git merge branch-name
在進入一個分支后翅楼,可以用這個命令與另外一個分支合并。但是合并可能失敗真慢,也就是發(fā)生沖突毅臊。即兩個分支中存在同名文件,但是文件內(nèi)容不一樣晤碘,Git就不知道保留哪一個文件褂微,這就需要我們手動修改沖突文件后再合并。
刪除分支
git branch -d branch-name
查看修改細(xì)節(jié)
git diff # 比較工作區(qū)和暫存區(qū)
git diff id_1 id_2 # 比較兩個歷史版本
git diff id # 比較工作區(qū)與這個版本
git diff --cached id # 比較暫存區(qū)與這個版本
這個命令是不難园爷,但是會輸出很多的內(nèi)容宠蚂,內(nèi)容就是兩個版本比較后的差異,看起來比較麻煩童社。
Github
Github就是一個遠(yuǎn)程倉庫求厕,可以把我們剛才提到的Git倉庫在他們那保存一份。這樣的好處就是扰楼,不容易丟失呀癣,可以讓更多的人參與進來。
所以會了Git以后Github的使用也就會了弦赖,它就是幫我們保存的项栏,所以平時的操作就是兩個:
把我的倉庫放過去
git push
把遠(yuǎn)程的倉庫拿過來
git clone