前言
本文主要記錄自己平時(shí)經(jīng)常使用的git命令和收集別人博客中一些常用命令,方便初學(xué)者理解和使用。
本文先簡(jiǎn)單介紹git工作原理,然后詳細(xì)介紹git的各種使用方法。
1. git工作原理
一開始的時(shí)候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當(dāng)前分支,以及當(dāng)前分支的提交點(diǎn):

每次提交,master分支都會(huì)向前移動(dòng)一步。
當(dāng)我們創(chuàng)建新的分支,例如dev時(shí),Git新建了一個(gè)指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當(dāng)前分支在dev上:

Git創(chuàng)建一個(gè)分支很快,因?yàn)槌嗽黾右粋€(gè)dev指針,改改HEAD的指向,工作區(qū)的文件都沒有任何變化!
對(duì)工作區(qū)的修改和提交就是針對(duì)dev分支了,比如新提交一次后,dev指針往前移動(dòng)一步,而master指針不變:

假如我們?cè)赿ev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最簡(jiǎn)單的方法,就是直接把master指向dev的當(dāng)前提交,就完成了合并:

所以Git合并分支也很快!就改改指針,工作區(qū)內(nèi)容也不變!
合并完分支后,我們可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支:

關(guān)于HEAD:
當(dāng)前版本: HEAD
上一個(gè)版本: HEAD^,
上上一個(gè)版本: HEAD^^
之前100個(gè)版本: HEAD~100
準(zhǔn)確定位某次提交:commit_id
首先,我們?cè)趃itub上創(chuàng)建了自己的倉(cāng)庫(kù),然后需要把github上的代碼拉到本地。
2. 拉代碼
2.1 克?。ǖ谝淮卫〈a)
第一次拉代碼,叫克隆clone。點(diǎn)擊“clone or download”,復(fù)制。如我的地址是 https://github.com/imutlxy/blog_code.git。
切換到你想放項(xiàng)目的目錄下,然后執(zhí)行:
git clone 項(xiàng)目地址(如:https://github.com/imutlxy/blog_code.git)
2.2 檢出分支
就是把遠(yuǎn)程分支的代碼checkout到本地
git checkout 分支名
2.3 從遠(yuǎn)端拉取最新代碼
前提條件:已經(jīng)clone了某個(gè)倉(cāng)庫(kù)到本地,并且已經(jīng)檢出某個(gè)分支到本地,當(dāng)該分支遠(yuǎn)端分支更新時(shí),我們可以通過git pull 來拉取最新代碼到本地。
git pull
3. 查看有哪些分支,查看當(dāng)前位于哪個(gè)分支
//只顯示本地分支
git branch
//顯示本地和遠(yuǎn)端的所有分支
git branch -a
結(jié)果如下:

帶*號(hào)的 master表示:當(dāng)前位于master分支。
remotes/origin/master表示:遠(yuǎn)端只有一個(gè)master分支。
帶remotes的都是遠(yuǎn)端分支。
4. 在本地新建分支,并推送到遠(yuǎn)端
一般master是主分支,放著線上的代碼。我們開發(fā)一般用developer分支,所以,我們先來新建一個(gè)分支,并且把它推送到遠(yuǎn)端。
4.1 在本地新建分支
在本地新建分支:
git branch 分支名(比如這里是 developers)
執(zhí)行 git branch -a 查看一下有沒有建成功:

好了,已經(jīng)ok了,然后我們需要切換到developer分支上
4.2 切換分支
git checkout developer
結(jié)果如下:

也可以直接下面這條命令來實(shí)現(xiàn)創(chuàng)建分支并切換到該分支:
git checkout -b 新建分支名
4.3 將本地新建分支推送到遠(yuǎn)端
git push origin developer
看結(jié)果,已經(jīng)有了一個(gè)remotes/origin/developer分支。

5. 刪除分支
5.1 刪除本地分支
從這節(jié)開始就不上圖了,除非有必要。大家可以自己去敲驗(yàn)證的命令。
如果你新建了一個(gè)分支還沒上傳到遠(yuǎn)端,現(xiàn)在想刪除它。例如
git branch --delete 分支名(這里是test)
或
git branch -d 分支名
5.2 強(qiáng)行刪除本地分支
注意:如果當(dāng)前分支還沒有被合并,刪除失敗,git會(huì)提示你。如果想強(qiáng)行刪除:
git branch -D 分支名
5.3 刪除遠(yuǎn)端分支
如果分支已經(jīng)推送到了遠(yuǎn)端:
git push origin --delete 分支名(這里是test)
6. 提交代碼到遠(yuǎn)端
當(dāng)我們修改了一些內(nèi)容后,想提交到遠(yuǎn)端,可以依次執(zhí)行:
git status
git add .
git commit -m "注釋:表示此次提交是完成了哪些功能"
git push origin 分支名
下面逐個(gè)講解這些命令的含義和使用方法。
6.1 查看有哪些文件修改了
git status
如下圖,紅色的文件就是有改動(dòng)的。BuildConfig.java,Manifest.java,R.java,這三個(gè)文件被刪除,delete,README.md和MainActivity.java被修改,modify。

6.2 git add
git add命令主要用于把修改了的文件存到暫存區(qū)中。
添加一個(gè)文件到暫存區(qū):(注意:需要進(jìn)入到該文件所在的目錄)
git add 文件名
添加全部改動(dòng)的文件到暫存區(qū):
git add .
當(dāng)添加完后,被添加的文件變?yōu)榱司G色。用 git status就可以看到,這里不貼圖。
6.3 將索引庫(kù)中的文件添加到本地倉(cāng)庫(kù)中
git commit -m "注釋:表示這次提交什么功能"
6.2我們將需要提交的文件添加到了索引庫(kù)中,然后我們需要將這些文件提交到本地倉(cāng)庫(kù)。執(zhí)行完 git commit 后,再用 git status 查看文件狀態(tài),發(fā)現(xiàn) git add 的那些文件都沒有了。
6.4 將本地倉(cāng)庫(kù)中的文件推送到遠(yuǎn)端
git push origin 分支名
如果這個(gè)分支是本地新建的,還沒有推送到遠(yuǎn)端,用這個(gè)命令也可以同時(shí)把本地分支提交到遠(yuǎn)端,同時(shí)提交本地修改。
這時(shí)候,你的所有改動(dòng)就都push到遠(yuǎn)端了,你可以在github上看到提交記錄。
7 合并分支
7.1 合并指定分支到當(dāng)前分支
上面我們?cè)趖est分支上完成了功能,此時(shí)我們需要把test分支修改的東西合并到developer分支上。
-
我們先切換到developer分支:
git checkout developer -
然后 再merge
git merge 分支名(這里是test)
此時(shí),我們就看之前提交到test分支上的內(nèi)容,在developer分支也能看到了。
7.2 解決沖突再合并
如果沒有沖突,那當(dāng)然是最好的,但很多時(shí)候merge時(shí)會(huì)有沖突,我們需要先解決沖突再合并。
比如:我現(xiàn)在在test分支上,README文件內(nèi)容是這樣的:

然后我們修改成這樣:

此時(shí)我們依次執(zhí)行
git add README.md
git commit -m "修改README"
git checkout developer
git merge test
看結(jié)果:

README出現(xiàn)conflict了,merge failed。
我們?cè)賮砜纯碦EADME內(nèi)容:

吶,<<<<<<<指的是改動(dòng)之前的內(nèi)容,======作為分隔符,>>>>>>>指的是改動(dòng)之后的內(nèi)容。我們?cè)摻鉀Q沖突了,這里留下后面改動(dòng)的,刪掉之前的內(nèi)容。然后再將修改后的文件重新提交即可。
8. 查看提交記錄
//查看當(dāng)前分支的提交記錄
git log
//查看指定分支的提交記錄
git log 分支名
9. 查看忽略的文件
通常有些文件無需納入 Git 的管理,也不希望它們總出現(xiàn)在未跟蹤文件列表。通常都是些自動(dòng)生成的文件,比如日志文件,或者編譯過程中創(chuàng)建的臨時(shí)文件等。我們可以創(chuàng)建一個(gè)名為 .gitignore 的文件,列出要忽略的文件模式。android studio創(chuàng)建project時(shí)會(huì)自動(dòng)生成一個(gè).gitignore 的文件。
查看忽略文件:
cat .gitignore
如下圖:

我們可以自己編輯 gitignore 文件,添加別的需要忽略的文件。
10.關(guān)于撤銷
10.1 撤銷工作區(qū)的修改
場(chǎng)景一:
我修改了README.md文件,但是還沒有執(zhí)行 git add,此時(shí),我不想要這些修改了,我要放棄這些修改,也就是回到之前沒有任何修改的狀態(tài)。
//放棄單個(gè)文件
git checkout 文件名
//放棄全部修改
git checkout .
10.2 撤銷暫存區(qū)的修改
場(chǎng)景二:
-
接著上面的問題,如果我已經(jīng)把這些修改的文件都添加到了暫存區(qū)中,也就是我執(zhí)行了git add,但還沒執(zhí)行 git commit,這時(shí)如果想撤銷這些修改,重新放回工作區(qū),可以執(zhí)行:
//撤銷某個(gè)文件
git reset HEAD 文件名//撤銷全部文件,全部放回工作區(qū)
git reset HEAD
-
如果徹底不想要這些暫存區(qū)中的文件,也就是撤銷此次所有修改,并且不放回工作區(qū),可以執(zhí)行:
git reset --hard
10.3 撤銷本地倉(cāng)庫(kù)的提交
場(chǎng)景三:
我修改了文件,然后依次執(zhí)行了 git add ,git commit,但我還沒執(zhí)行 git push,此時(shí)我發(fā)現(xiàn)自己提交錯(cuò)了文件,我想撤銷此次提交,回到上次提交的狀態(tài)??梢詧?zhí)行:
git reset --hard HEAD^
我們來實(shí)際模擬一下場(chǎng)景。
- 用git log看一下提交記錄,我們看到,最近一次提交記錄是“初次提交工程”,再前一次是“test。

- 然后我們修改README文件,并且提交到本地倉(cāng)庫(kù),也就是執(zhí)行g(shù)it commit -m "修改README--1",如下:

再看一下提交記錄:

- 撤銷剛才的提交記錄,回到上一次提交記錄,即"初次提交工程"。

看到了嗎,之前的提交竟然消失了!README內(nèi)容也回到之前的樣子。
-
如果你又想再回到剛才撤銷記錄的狀態(tài),怎么辦?
git reset --hard 剛才提交記錄的版本號(hào)(這里是1883cb1df1bd670088e1cf82de18967076d1754f).到這里大家可能會(huì)問,怎么拿到這個(gè)記錄的版本號(hào)呢?
git reflog

看到?jīng)],git會(huì)記錄你的每一次記錄!在git,是有后悔藥的?。。?/p>
11. 比較提交
11.1 比較兩個(gè)分支的差異
git diff master..test
11.2 查看當(dāng)前分支工作區(qū)與緩沖區(qū)的差異
會(huì)詳細(xì)列出修改內(nèi)容
git diff
11.3 查看緩存區(qū)和上次提交的差異
顯示你當(dāng)前的索引和上次提交間的差異(這次git add 和 上次git commit的差異),也是下次提交時(shí)要提交的內(nèi)容(staged,添加到索引中):
git diff --cached
//可以具體定位到某一個(gè)文件
git diff --cached filename

11.4 查看當(dāng)前分支與其他指定分支的差異
git diff 指定分支名
//也以加上路徑限定符,來只 比較某一個(gè)文件或目錄。
git diff HEAD -- ./lib
11.5 查看有哪些文件有改動(dòng)(只簡(jiǎn)單列出改動(dòng)的文件名)
如果不是查看每個(gè)文件的詳細(xì)差別,而是統(tǒng)計(jì)一下有哪些文件被改動(dòng),有多少行被改動(dòng),就可以使用‘--stat' 參數(shù)。
git diff --stat
如下圖,BuildConfig.java,Manifest.java,R.java,README.md,MainActivity.java這幾個(gè)文件被改動(dòng)。

11.6 查看某兩個(gè)版本之間的差異
git diff 版本號(hào)1 版本號(hào)2
11.7 查看某兩個(gè)版本的某個(gè)文件之間的差異
git diff 版本號(hào)1:filename 版本號(hào)2:filename
12 把當(dāng)前目錄變成Git可以管理的倉(cāng)庫(kù)
當(dāng)你在本地新建了一個(gè)倉(cāng)庫(kù),可以通過以下命令把它變成git管理倉(cāng)庫(kù):
git init
參考: