git命令篇

初始化一個(gè)Git倉(cāng)庫(kù),使用git init命令。

添加?文件到Git倉(cāng)庫(kù),分兩步:

? 第一步,使用命令git add ,注意,可反復(fù)多次使用,添加多個(gè)文件;

? 第二步,使用命令git commit,完成。


git status命令可以讓我們時(shí)刻掌握倉(cāng)庫(kù)當(dāng)前的狀態(tài),上?面的命令告訴我們,readme.txt被

修改過了,但還沒有準(zhǔn)備提交的修改。


的。比如你休假兩周從國(guó)外回來(lái),第?一天上班時(shí),已經(jīng)記不清上次怎么修改的

readme.txt,所以,需要用git diff這個(gè)命令看看:

?git diff readme.txt


當(dāng)然了,在實(shí)際?工作中,我們腦子里怎么可能記得?一個(gè)?幾千?行的文件每次都改了什么內(nèi)容,

不然要版本控制系統(tǒng)干什么。版本控制系統(tǒng)肯定有某個(gè)命令可以告訴我們歷史記錄,在Git

中,我們用git log命令查看:

如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上

--pretty=oneline參數(shù):

git log --pretty=oneline

首先,Git必須知道當(dāng)前版本是哪個(gè)版本,在Git中,用HEAD表?示當(dāng)前版本,也就是最新的

提交“ 3628164...882e1e0”(注意我的提交ID和你的肯定不一樣),上一個(gè)版本就是

HEAD^,上上一個(gè)版本就是HEAD^^,當(dāng)然往上100 個(gè)版本寫100個(gè)^比較容易數(shù)不過來(lái),

所以寫成HEAD~100。

現(xiàn)在,我們要把當(dāng)前版本“append GPL”回退到上?一個(gè)版本“add distributed”,就可

以使?用git reset命令:

git reset --hard HEAD^

Git提供了一個(gè)命令git reflog?用來(lái)記錄你的每一次命令:

git reflog

ea34578 HEAD@{0}: reset: moving to HEAD^

3628164 HEAD@{1}: commit: append GPL

ea34578 HEAD@{2}: commit: add distributed

cb926e7 HEAD@{3}: commit (initial): wrote a readme file

終于舒了?口?氣,第二行顯?示“append GPL”的commit id是3628164,現(xiàn)在,你?又可以乘

坐時(shí)光機(jī)回到未來(lái)了。

現(xiàn)在總結(jié)?一下:

? HEAD指向的版本就是當(dāng)前版本,因此,Git允許我們?cè)诎姹镜臍v史之間穿梭,使用命

令? git reset --hard commit_id。

? 穿梭前,?用git log可以查看提交歷史,以便確定要回退到哪個(gè)版本。

? 要重返未來(lái),?用git reflog查看命令歷史,以便確定要回到未來(lái)的哪個(gè)版本。




git checkout -- readme.txt

命令git checkout -- readme.txt意思就是,把readme.txt?文件在?工作區(qū)的修改全部撤銷,這

?里有兩種情況:

一種是readme.txt自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫(kù)一模一

樣的狀態(tài);

一種是readme.txt已經(jīng)添加到暫存區(qū)后,又作了修改,現(xiàn)在,撤銷修改就回到添加到暫存

區(qū)后的狀態(tài)。

總之,就是讓這個(gè)文件回到最近一次git commit或git add時(shí)的狀態(tài)。

現(xiàn)在,看看readme.txt的?文件內(nèi)容:

$ cat readme.txt

Git is a distributed version control system.

Git is free software distributed under the GPL.

Git has a mutable index called stage.

Git tracks changes of files.

文件內(nèi)容果然復(fù)原了。

git checkout -- file命令中的“--”很重要,沒有“--”,就變成了“創(chuàng)建?一個(gè)新分?支”的命

令,我們?cè)诤?面的分?支管理中會(huì)再次遇到git checkout命令。



Git同樣告訴我們,.用命令git reset HEAD file可以把暫存區(qū)的修改撤銷掉(unstage),重

新放回.工作區(qū):

git reset HEAD readme.txt


git reset命令既可以回退版本,也可以把暫存區(qū)的修改回退到.工作區(qū)。當(dāng)我們.用HEAD時(shí),

表.示最新的版本。


還記得如何丟棄.工作區(qū)的修改嗎?

git checkout -- readme.txt

git status

# On branch master

nothing to commit (working directory clean)

整個(gè)世界終于清靜了!

現(xiàn)在,假設(shè)你不但改錯(cuò)了東.西,還從暫存區(qū)提交到了版本庫(kù),怎么辦呢?還記得版本回退.一

節(jié)嗎?可以回退到上.一個(gè)版本。不過,這是有條件的,就是你還沒有把.自.己的本地版本庫(kù)推

送到遠(yuǎn)程。還記得Git是分布式版本控制系統(tǒng)嗎?我們后.面會(huì)講到遠(yuǎn)程版本庫(kù),.一旦你

把“stupid boss”提交推送到遠(yuǎn)程版本庫(kù),你就真的慘了……

############### 重點(diǎn)

總結(jié): 沒有 git add 之前的修改? ?用??git checkout -- readme.txt 撤銷修改

git add 之后的修改:? 先執(zhí)行 git reset HEAD file,后 執(zhí)行?git checkout -- readme.txt?

git commit之后的修改 用? ?git reset --hard commit_id?

如果已經(jīng) git push了, ohYear , 你沒得救了.


場(chǎng)景1:當(dāng)你改亂了.工作區(qū)某個(gè).文件的內(nèi)容,想直接丟棄.工作區(qū)的修改時(shí),.用命令git

checkout -- file。? (git add 之前 )

場(chǎng)景2:當(dāng)你不但改亂了.工作區(qū)某個(gè).文件的內(nèi)容,還添加到了暫存區(qū)時(shí),想丟棄修改,分兩

步,第.一步.用命令git reset HEAD file,就回到了場(chǎng)景1,第.二步按場(chǎng)景1操作。(git add之后)

場(chǎng)景3:已經(jīng)提交了不合適的修改到版本庫(kù)時(shí),想要撤銷本次提交,參考版本回退.一節(jié),不

過前提是沒有推送到遠(yuǎn)程庫(kù)。(git commit 之后)


############### 重點(diǎn)


一是確實(shí)要從版本庫(kù)中刪除該?文件,那就用命令git rm刪掉,并且

commit:

git rm test.txt

rm 'test.txt'

git commit -m "remove test.txt"

[master d17efd8] remove test.txt

1 file changed, 1 deletion(-)

delete mode 100644 test.txt

現(xiàn)在,?文件就從版本庫(kù)中被刪除了。

另一種情況是刪錯(cuò)了,因?yàn)榘姹編?kù)?里還有呢,所以可以很輕松地把誤刪的?文件恢復(fù)到最新版

本:

git checkout -- test.txt

git checkout其實(shí)是?用版本庫(kù)?里的版本替換?工作區(qū)的版本,?無(wú)論?工作區(qū)是修改還是刪除,都

可以“一鍵還原”。


要關(guān)聯(lián).一個(gè)遠(yuǎn)程庫(kù),使.用命令git remote add origin git@server-name:path/repo-name.git;

關(guān)聯(lián)后,使.用命令git push -u origin master第.一次推送master分.支的所有內(nèi)容;

此后,每次本地提交后,只要有必要,就可以使.用命令git push origin master推送最新修

改;

分布式版本系統(tǒng)的最.大好處之.一是在本地.工作完全不需要考慮遠(yuǎn)程庫(kù)的存在,也就是有沒有

聯(lián)..網(wǎng)都可以正常.工作,.而SVN在沒有聯(lián)..網(wǎng)的時(shí)候是拒絕干活的!當(dāng)有..網(wǎng)絡(luò)的時(shí)候,再把本地

提交推送.一下就完成了同步,真是太.方便了!



分支:


首先,我們創(chuàng)建dev分?支,然后切換到dev分?支:

git checkout -b dev

Switched to a new branch 'dev'

git checkout命令加上-b參數(shù)表?示創(chuàng)建并切換,相當(dāng)于以下兩條命令:

git branch dev

git checkout dev

Switched to branch 'dev'

然后,?用git branch命令查看當(dāng)前分?支:

git branch

* dev

master

git branch命令會(huì)列出所有分?支,當(dāng)前分?支前?面會(huì)標(biāo)?一個(gè)*號(hào)。


現(xiàn)在,我們把dev分?支的?工作成果合并到master分?支上:

$ git merge dev

Updating d17efd8..fec145a

Fast-forward

readme.txt | 1 +

1 file changed, 1 insertion(+)

git merge命令?用于合并指定分?支到當(dāng)前分?支。合并后,再查看readme.txt的內(nèi)容,就可以

看到,和dev分支的最新提交是完全一樣的。

注意到上面的Fast-forward信息,Git告訴我們,這次合并是“快進(jìn)模式”,也就是直接把

master指向dev的當(dāng)前提交,所以合并速度非常快。

當(dāng)然,也不是每次合并都能Fast-forward,我們后?面會(huì)將其他?方式的合并。

合并完成后,就可以放?心地刪除dev分支了:

$ git branch -d dev

Deleted branch dev (was fec145a).


刪除后,查看branch,就只剩下master分?支了:

$ git branch

* master

因?yàn)閯?chuàng)建、合并和刪除分?支?非??欤訥it?鼓勵(lì)你使用分支完成某個(gè)任務(wù),合并后再刪掉

分支,這和直接在master分?支上工作效果是一樣的,但過程更安全。


Git鼓勵(lì)?大量使用分支:

查看分支:git branch

創(chuàng)建分支:git branch name

切換分支:git checkout name

創(chuàng)建+切換分支:git checkout -b name

合并某分支到當(dāng)前分支:git merge name

刪除分支:git branch -d name


.用帶參數(shù)的git log也可以看到分?支的合并情況:

$ git log --graph --pretty=oneline --abbrev-commit


現(xiàn)在,我們切換回master:

$ git checkout master

Switched to branch 'master'

準(zhǔn)備合并dev分.支,請(qǐng)注意--no-ff參數(shù),表.示禁.用“Fast forward”:

$ git merge --no-ff -m "merge with no-ff" dev

Merge made by the 'recursive' strategy.

readme.txt | 1 +

1 file changed, 1 insertion(+)

因?yàn)楸敬魏喜⒁獎(jiǎng)?chuàng)建.一個(gè)新的commit,所以加上-m參數(shù),把commit描述寫進(jìn)去。

合并后,我們.用git log看看分.支歷史:

$ git log --graph --pretty=oneline --abbrev-commit


開發(fā).一個(gè)新feature,最好新建.一個(gè)分支;

如果要丟棄.一個(gè)沒有被合并過的分支,可以通過git branch -D name強(qiáng).行刪除。


信可以用git branch命令看看:

$ git branch

* master

現(xiàn)在,你的?小伙伴要在dev分支上開發(fā),就必須創(chuàng)建遠(yuǎn)程origin的dev分支到本地,于是他

?用這個(gè)命令創(chuàng)建本地dev分支:

$ git checkout -b dev origin/dev

現(xiàn)在,他就可以在dev上繼續(xù)修改,然后,時(shí)不時(shí)地把dev分支push到遠(yuǎn)程:


git pull也失敗了,原因是沒有指定本地dev分支與遠(yuǎn)程origin/dev分支的鏈接,根據(jù)提示,

設(shè)置dev和origin/dev的鏈接:

$ git branch --set-upstream dev origin/dev

Branch dev set up to track remote branch dev from origin.

再pull:

$ git pull

Auto-merging hello.py

CONFLICT (content): Merge conflict in hello.py

Automatic merge failed; fix conflicts and then commit the result.

這回git pull成功,但是合并有沖突,需要?手動(dòng)解決,解決的方法和分支管理中的解決沖突完

全?一樣。解決后,提交,再push.


多人協(xié)作的?工作模式通常是這樣:

1. ?首先,可以試圖用git push origin branch-name推送自己的修改;

2. 如果推送失敗,則因?yàn)檫h(yuǎn)程分?支?比你的本地更新,需要先用git pull試圖合并;

3. 如果合并有沖突,則解決沖突,并在本地提交;

4. 沒有沖突或者解決掉沖突后,再?用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,則說(shuō)明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒

有創(chuàng)建,用命令git branch --set-upstream branch-name origin/branch-name。

這就是多人協(xié)作的工作模式,一旦熟悉了,就非常簡(jiǎn)單.



查看遠(yuǎn)程庫(kù)信息,使?用git remote -v;

? 本地新建的分支如果不推送到遠(yuǎn)程,對(duì)其他?人就是不可見的;

? 從本地推送分支,使?用git push origin branch-name,如果推送失敗,先?用git pull抓

取遠(yuǎn)程的新提交;

? 在本地創(chuàng)建和遠(yuǎn)程分支對(duì)應(yīng)的分?支,使用git checkout -b branch-name origin/branchname,

本地和遠(yuǎn)程分支的名稱最好一致;

? 建?立本地分支和遠(yuǎn)程分支的關(guān)聯(lián),使?用git branch --set-upstream branch-name

origin/branch-name;

? 從遠(yuǎn)程抓取分支,使?用git pull,如果有沖突,要先處理沖突。


創(chuàng)建標(biāo)簽:

命令git tag name?用于新建?一個(gè)標(biāo)簽,默認(rèn)為HEAD,也可以指定?一個(gè)commit id;

-a tagname -m "blablabla..."可以指定標(biāo)簽信息;

命令git tag可以查看所有標(biāo)簽;


命令git push origin tagname可以推送?一個(gè)本地標(biāo)簽;

? 命令git push origin --tags可以推送全部未推送過的本地標(biāo)簽;

? 命令git tag -d tagname可以刪除?一個(gè)本地標(biāo)簽;

? 命令git push origin :refs/tags/tagname可以刪除?一個(gè)遠(yuǎn)程標(biāo)簽。










...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容