| 命令 | 作用 |
|---|---|
| git init | 在某目錄(不一定是空目錄)中初始化一個(gè)空的Git倉庫(empty Git repository) |
| git add | 添加文件到暫存區(qū) |
| git commit -m "注釋" | 將暫存區(qū)里的改動(dòng)給提交到本地的版本庫 |
| git status | 查看最后一次git commit之后文件又有哪些新的改動(dòng) |
| git diff | 查看具體改動(dòng)的細(xì)節(jié) |
| git log | 查看歷次commit,不會(huì)顯示因reset而被抹掉的commit |
| git reflog | 查看歷次commit,包括因reset而被抹掉的commit,所以通常只在打算reset到更加新的commit的時(shí)候才用 |
| git reset --hard HEAD^ | 屬于回退操作: 立即回退到上1個(gè)commit |
| git reset --hard HEAD~1 | 屬于回退操作: 同上 |
| git reset --hard 109534a | 屬于回退操作: 立即還原到HEAD以109534a開頭的commit |
| git checkout -- xxx.txt | 屬于回退操作: 在沒有add文件之前,打算回退對(duì)文件的修改,但是編輯器又關(guān)掉了,無法Ctrl+Z,此時(shí)可以用checkout,原理是從最后一個(gè)commit中找到這的文件,然后還原 |
| git reset HEAD xxx.txt |
屬于回退操作: 類似上一條,在add文件之后,打算回退對(duì)文件的修改,就先用這條命令,然后再用git checkout -- xxx.txt。git reset HEAD xxx.txt是git add xxx.txt的反操作。可見,git reset命令既可以回退版本,也可以把暫存區(qū)的修改回退到工作區(qū)。當(dāng)我們用HEAD時(shí),表示最新的版本。 |
| git rm | 刪除一個(gè)工作區(qū)內(nèi)的文件,跟平常利用IDE或者操作系統(tǒng)刪除文件是一樣的效果,通常沒必要用這個(gè)命令 |
| git remote add origin git@github.com:michaelliao/learngit.git | 將遠(yuǎn)程倉庫添加到本地,遠(yuǎn)程倉庫默認(rèn)叫origin |
| git push -u origin master | 先在遠(yuǎn)程倉庫建立叫master的分支,然后提交代碼到遠(yuǎn)程倉庫的master分支,這個(gè)帶-u的命令通常只需最早的時(shí)候執(zhí)行一次 |
| git push origin master | 常用命令,將當(dāng)前本地分支推送到遠(yuǎn)程origin倉庫的master分支,如果遠(yuǎn)程的倉庫正好叫origin,且分支正好是master,則通常origin master可以省略 |
| git push origin dev | 類似上條,遠(yuǎn)程分支叫dev |
| git clone git@github.com:michaelliao/gitskills.git | 克隆一個(gè)遠(yuǎn)程庫到本地 |
| git branch dev | 創(chuàng)建dev分支,此時(shí),比如當(dāng)前分支是master分支,那么dev分支與master分支同時(shí)指向了最新的那個(gè)commit |
| git branch -d dev | 刪除dev分支 |
| git checkout dev | 切換到dev分支,這一步屬于危險(xiǎn)操作,因?yàn)闀?huì)覆蓋工作區(qū),也會(huì)清空暫存區(qū),所以請(qǐng)先確保工作區(qū)的文件都已經(jīng)add,暫存區(qū)的文件都已經(jīng)commit |
| git checkout -b dev | 創(chuàng)建dev并立即切換到dev分支,等于2條命令的合并:git branch dev(創(chuàng)建分支)和git checkout dev(切換分支) |
| git branch | 查看所有分支概況 |
| git merge dev | 將dev合并到當(dāng)前分支上 |
| git stash | 將沒有add的所有代碼全部儲(chǔ)存到某個(gè)棧,然后將工作區(qū)恢復(fù)到上一次add之前的狀態(tài),這個(gè)功能用于:1、手頭工作沒完成,線上出了bug,所以你需要工作區(qū)回退到線上版本,然后改bug,然后立即提交,然后繼續(xù)你手頭工作,這時(shí)候用stash可以儲(chǔ)存你的手頭工作,等bug修復(fù)了,再用git stash apply還原手頭工作。2、你想嘗試一種編程思路,但是不確定是否可行,這時(shí)候你可以儲(chǔ)存你的代碼,然后繼續(xù)嘗試,半個(gè)小時(shí)之后你可能發(fā)現(xiàn)確實(shí)行不通,那么立即用git stash apply還原。 |
| git stash apply | 將stash儲(chǔ)存的最新的那個(gè)狀態(tài)還原出來 |
| git stash apply stash@{0} | 將stash儲(chǔ)存的編號(hào)為0的狀態(tài)還原出來 |
| git stash drop | 刪掉最新的那個(gè)狀態(tài) |
| git stash pop | 將stash儲(chǔ)存的狀態(tài)還原出來同時(shí)刪掉這個(gè)狀態(tài) |
| git stash list | 所有stash過的狀態(tài)列表 |
| git branch -D <name> | 強(qiáng)制刪除未被合并的分支 |
| git remote | 查看遠(yuǎn)程倉庫的名稱,遠(yuǎn)程庫默認(rèn)名稱就是origin
|
| git remote -v | 同上,只是更詳細(xì) |
| git tag v1.0 | 給當(dāng)前最新的commit打一個(gè)標(biāo)簽叫做v1.0
|
| git log --pretty=oneline --abbrev-commit | 查看歷史所有commit跟標(biāo)簽的對(duì)應(yīng)關(guān)系 |
| git tag v0.9 f52c633 | 從上句命令的結(jié)果中查出歷史的某個(gè)commit,然后給它打標(biāo)簽 |
| git tag | 列出所有標(biāo)簽,按照字母順序排列 |
| git show v0.9 | 查看該標(biāo)簽的具體信息 |
| git tag -a v0.1 -m "version 0.1 released" 1094adb | 給1094adb打標(biāo)簽且加注釋 |
| git tag -d v0.1 | 刪除標(biāo)簽 |
| 名詞 | 解釋 |
|---|---|
| origin | 遠(yuǎn)程倉庫的默認(rèn)名稱 |
| 工作區(qū)(Working Directory) | 程序員在電腦里能看到的目錄 |
| 版本庫(Repository) | .git目錄 |
| 暫存區(qū)(stage或者叫index) | 只用來暫存git add的文件,一旦commit,就清空暫存區(qū) |
| 分支(branch) | 一個(gè)工程可以有不同的分支,以便于多人協(xié)同工作 |
| master分支 | git工程初始化之后默認(rèn)生成的第一個(gè)分支 |
| HEAD | 一個(gè)指針,用于指向某個(gè)分支,而該分支指向的commit是確定的,所以你可以說HEAD是指向分支的,也可以說是指向commit的。 |
| 提交(commit) | 提交跟分支的關(guān)系是,提交是基于時(shí)間軸的,分支是提交身上掛著的一個(gè)標(biāo)簽,一個(gè)提交可以有多個(gè)分支標(biāo)簽,一個(gè)提交可以既屬于master分支,也屬于dev分支,還屬于其他xxx分支?,F(xiàn)在,把所有帶有dev分支標(biāo)簽的提交高亮,串起來,就形成了dev分支概念。同樣的代碼commit到不同分支,就等于多個(gè)分支都指向這個(gè)commit |
| 快進(jìn)模式(Fast forward模式) | 默認(rèn)的合并方式,將落后的那個(gè)分支快進(jìn)到領(lǐng)先的那個(gè)分支上,無論當(dāng)前分支是領(lǐng)先的還是落后的分支,不產(chǎn)生新的commit |
| git merge --no-ff -m "注釋" dev | 禁用快進(jìn)模式的合并方式,效果是,dev分支不做任何改變,新建一個(gè)commit,最后讓當(dāng)前分支(比如master分支)指向這個(gè)commit,這個(gè)commit就是合并的結(jié)果。跟FF模式的區(qū)別在于產(chǎn)生新的commit |
解決合并沖突
2個(gè)分支的文件發(fā)生沖突的時(shí)候,VS Code會(huì)給你4個(gè)選擇,選擇其一之后,保存文件,然后git add 該文件,然后commit,這時(shí)候再合并就沒問題了。
分支策略
在實(shí)際開發(fā)中,我們應(yīng)該按照幾個(gè)基本原則進(jìn)行分支管理:
首先,master分支應(yīng)該是非常穩(wěn)定的,也就是僅用來發(fā)布新版本,平時(shí)不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是說,dev分支是不穩(wěn)定的,到某個(gè)時(shí)候,比如1.0版本發(fā)布時(shí),再把dev分支合并到master上,在master分支發(fā)布1.0版本;
你和你的小伙伴們每個(gè)人都在dev分支上干活,每個(gè)人都有自己的分支,時(shí)不時(shí)地往dev分支上合并就可以了。
所以,團(tuán)隊(duì)合作的分支看起來就像這樣:
哪些分支需要推送,哪些不需要呢?
master分支是主分支,因此要時(shí)刻與遠(yuǎn)程同步;
dev分支是開發(fā)分支,團(tuán)隊(duì)所有成員都需要在上面工作,所以也需要與遠(yuǎn)程同步;
bug分支只用于在本地修復(fù)bug,就沒必要推到遠(yuǎn)程了,除非老板要看看你每周到底修復(fù)了幾個(gè)bug;
feature分支是否推到遠(yuǎn)程,取決于你是否和你的小伙伴合作在上面開發(fā)。
總之,就是在Git中,分支完全可以在本地自己藏著玩,是否推送,視你的心情而定!
當(dāng)你修改的文件有其他人也在修改,且他比你先推送到遠(yuǎn)程,怎么辦?
等你推送的時(shí)候會(huì)發(fā)生:
$ git push origin dev
To github.com:michaelliao/learngit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:michaelliao/learngit.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
意思是,你需要先把別人的新文件拉取下來,然后在你電腦里合并,然后才能推送。做法:先用git pull把最新的提交從origin/dev抓下來,然后,在本地合并,解決沖突,再推送。
第一步,如果你的本地分支跟遠(yuǎn)程分支沒有建立鏈接,則先建立鏈接:
git branch --set-upstream-to=origin/dev dev
origin/dev是遠(yuǎn)程分支,最后的dev是本地分支。
第二步,git pull。然后必然會(huì)提示文件沖突,git會(huì)自動(dòng)嘗試合并,不過大部分時(shí)候是失敗的,需要人腦合并。通常VS Code會(huì)給出便捷的合并提示。
第三步,git commit -m "fix env conflict"以及git push origin dev,就OK了。