快速上手Git版本控制
基本概念和操作
如何提交
git add . 添加所有文件
git commit -m "備注" 提交到本地版本庫

git add命令實際上就是把要提交的所有修改放到暫存區(qū)(Stage),
然后,執(zhí)行g(shù)it commit就可以一次性把暫存區(qū)的所有修改提交到分支。
提交之后是這樣的 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

git diff HEAD -- readme.txt 命令可以查看工作區(qū)和版本庫里面最新版本的區(qū)別
如何撤銷
git checkout -- filename 可以丟棄工作區(qū)的修改
git checkout -- file命令中的--很重要,沒有--,就變成了“
切換到另一個分支”的命令
git checkout 其實是用版本庫里的版本替換工作區(qū)的版本,無論工作區(qū)是修改還是刪除,都可以“一鍵還原”
遠程倉庫
查看遠程倉庫地址
git remote -v
把本地庫的內(nèi)容推送到遠程
git push 把當前分支推送到遠程,如果是從遠程倉庫clone出來的話可以直接使用。
本地作了提交,就可以通過命令
git push origin master
另外:
把本地的master分支,推送到遠程的origin倉庫
git push -u origin master
加上了-u參數(shù),Git不但會把本地的master分支內(nèi)容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關(guān)聯(lián)起來,在以后的推送或者拉取時就可以簡化命令。
要關(guān)聯(lián)一個遠程庫,使用命令:
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推送最新修改;
假設(shè)我們從零開發(fā),那么最好的方式是先創(chuàng)建遠程庫,然后,從遠程庫克?。?br>
git clone git@server-name:path/repo-name.git
git 支持HTTP和Git協(xié)議,HTTP一般更快一些。
分支詳解

每次提交,master分支都會向前移動一步,這樣,隨著你不斷提交,master分支的線也越來越長

創(chuàng)建了一個分支dev,Head指向到dev(dev變成當前分支)

從現(xiàn)在開始,對工作區(qū)的修改和提交就是針對dev分支了,比如新提交一次后,dev指針往前移動一步,而master指針不變。

假如我們在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合并。

如上圖所示,合并完分支后,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支。
別急,下面是分支的操作。
分支操作
拉取遠程分支
git checkout -b picking origin/picking 拉取遠程分支到本地(本地也創(chuàng)建了分支picking)
不要忘記-b 后兩個參數(shù),一個是本地分支叫picking,遠程分支origin/picking。
git checkout -b origin/picking,這個是錯誤的,這個只是創(chuàng)建了本地分支origin/picking
創(chuàng)建分支
git checkout 命令加上-b參數(shù)表示創(chuàng)建并切換。
例:
git checkout -b dev 創(chuàng)建(本地)分支 dev并切換。
切換分支
這里再次說明:切換分支就是 git checkout <branch>
git branch 命令會列出所有分支,當前分支前面會標一個 * 號。
例:命令窗口輸出
dell@dell-PC MINGW64 /e/IdeaProject/spring-framework (4.2.6.RELEASE)
$ git branch
* 4.2.6.RELEASE
4.2.x
master
git checkout master 回到master分支
刪除分支
git branch -d dev 刪除分支dev
git 鼓勵你使用分支完成某個任務(wù),合并后再刪掉分支。
合并分支的情況
有四種合并情況:
在master分支下:
git merge master;//將master合并到master上,自然master不會改變。git merge dev;//將dev合并到master上,自然dev不會發(fā)生改變;而master則需分情況討論,若master在dev之前則masterdev變?yōu)楹蚫ev一樣,若master在dev之后,則master不變。
在dev分支下:
git merge dev;//將dev合并到dev上,自然dev不會發(fā)生改變git merge master;//將master合并到dev上,自然master不會改變;而dev則需分情況討論,若dev在master之前則dev變?yōu)楹蚼aster一樣,若dev在master之后,則dev不變。
總而言之,任意在任意一個分支A下均可與其它分支(包括該分支自身)B和并,且和并后分支B不變,而分支A則變?yōu)榉种和B中較新的一個分支。
合并分支
合并分支是非常常見的操作:git merge命令用于合并指定分支到當前分支。
git merge dev 把dev分支合并到當前分支,不管在什么分支,都是把指定的分支合并到自己當前的分支。
開發(fā)中常常在dev分支開發(fā),如果需要拉取master上的提交,通常就是在dev分支下,git merge master,這樣代碼就是最新的了。
如果你在dev當前開發(fā)(提交)完成,確認沒有問題的時候,如果要(可以)合并到master了,
這時候切換到master分支,git checkout master,然后git merge dev。
FastForward
使用fastforward會丟失分支信息。git 默認是使用FastForward。一般禁止使用FastForward。
Fastforward就是直接將HEAD指向了dev最當前的版本,沒有產(chǎn)生新的提交,并且看不到原來的分支信息。
不使用FastForward
將dev合并到master(當前在master)
git merge --no-ff -m "merge with no-ff" dev
git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。


合并分支時,加上--no-ff參數(shù)(ff就是fastforward)就可以用普通模式合并,合并后的歷史有分支,能看出來曾經(jīng)做過合并,而fast forward合并就看不出來曾經(jīng)做過合并。
解決分支沖突
當Git無法自動合并分支時,就必須首先解決沖突。解決沖突后,再次提交,合并完成。一般JetBrains的IDE提供了很強大的可視化Merge功能。
推送分支
git push origin test
把當前分支推送到 遠程分支test
git push
直接推送本分支到遠程已經(jīng)關(guān)聯(lián)的分支
推送分支的三種情況
推送本地分支local_branch到遠程分支 remote_branch并建立關(guān)聯(lián)關(guān)系
| 遠程remote_branch分支 | 本地已經(jīng)切換到local_branch | 遠程關(guān)聯(lián)本地分支local_branch | 命令 |
|---|---|---|---|
| 已有 | 是 | 已經(jīng)關(guān)聯(lián) | git push |
| 已有 | 是 | 未關(guān)聯(lián) | git push -u origin/remote_branch |
| 沒有 | 是 | - | git push origin local_branch:remote_branch |
并不是一定要把本地分支往遠程推送,那么,哪些分支需要推送,哪些不需要呢?
| 場景 | 是否需要 | 理由 |
|---|---|---|
| master分支是主分支 | 必須 | 要時刻與遠程同步 |
| dev分支是開發(fā)分支 | 必須 | 團隊所有成員都需要在上面工作,所以也需要與遠程同步 |
| bug分支 | 可選 | 只用于在本地修復(fù)bug,就沒必要推到遠程了,除非老板要看看你每周到底修復(fù)了幾個bug |
| feature分支 | 看情況 | 是否推到遠程,取決于你是否和你的小伙伴合作在上面開發(fā) |
總之,就是在Git中,分支完全可以在本地,是否推送看自己!
臨時儲藏
Git還提供了一個stash功能,可以把當前工作現(xiàn)場“儲藏”起來,等以后恢復(fù)現(xiàn)場后繼續(xù)工作
查看臨時現(xiàn)場
git stash list
恢復(fù)現(xiàn)場
有兩個辦法,一是用git stash apply恢復(fù),但是恢復(fù)后,stash內(nèi)容并不刪除,你需要用git stash drop來刪除;
另一種方式是用git stash pop,恢復(fù)的同時把stash內(nèi)容也刪了。
標簽
git tag <name> 給當前分支 打個標簽
git tag v0.9 6224937 給歷史commit id加標簽
git tag -a v0.1 -m "version 0.1 released" 3628164 加上標簽時添加說明文字
git show <tagname> 查看標簽內(nèi)容
git push origin <tagname> 推送標簽到遠程
git checkout -b/B <localbranch> <tagname> 拉取遠程的Tag到本地分支localbranch
git push origin --tags 一次性推送全部尚未推送到遠程的本地標簽
刪除標簽
如果標簽已經(jīng)推送到遠程,要刪除遠程標簽就麻煩一點,先從本地刪除,然后,從遠程刪除。
git tag -d <tagname>
或者
git push origin :refs/tags/<tagname>
冒號左邊是空的,含義就是用空的推過去,表示不要了。
附常用命令
git commit提交到本地緩存
git diff 比較文件
git status 查看文件版本狀態(tài)
git log 查看版本歷史
git reset --hard Hard^ 回滾上一個版本
git reflog 查看commit ID
用戶
查看用戶名和郵箱地址:
git config user.name
git config user.email
修改用戶名和郵箱地址:
git config --global user.name "username"
git config --global user.email "xxx@xxx.com"
清除認證信息:
git credential-manager delete
這個命令適用于,當你提交的時候總是失敗,但是確定密碼正確的時候。
提交失?。?br> 基本上就是因為沒權(quán)限了。如果有,參考上面一條。
開源項目之路
多remote倉庫
已知已經(jīng)克隆了一個自己的倉庫,遠程倉庫名字叫做origin
下面需要增加一個遠程倉庫,命名github
git remote add github https://github.com/slankka/someRepo.git
這樣就有兩個遠程倉庫了。
git fetch github 可以拉取該分支的最新代碼到本地緩存,
合并需要用git pull github branchName
git fetch origin 可以拉取自己的倉庫最新代碼。
rebase 合并多個提交
例子:把前面兩個提交合并到第三個commit,最早提交的那個。
# git log
commit 06cb6a26492319985aac59bd7fc8be8514925381 (origin/IPVE-2018-06-14-SPL, IPVE-2018-06-14-SPL)
Author: slankka <cor_twi@outlook.com>
Date: Tue Jun 19 10:21:22 2018 +0800
最終改進
commit f5c61305441cc4266246539bc740647bd962c51f
Author: slankka <cor_twi@outlook.com>
Date: Fri Jun 15 18:48:31 2018 +0800
再次改進
commit 5a46753bc04240786a68bb54cd1fcfa9dd9f857e
Author: slankka <cor_twi@outlook.com>
Date: Fri Jun 15 17:00:01 2018 +0800
我提交了一個特性
輸入:rebase -i 5a4675
然后會有一個文本被打開
pick f5c61305 再次改進
pick 06cb6a26 最終改進
# Rebase 5a46753b..06cb6a26 onto 5a46753b (2 commands)
意思就是 把這三個提交rebase到最早的提交(我提交了一個特性)這里。
把第二個pick改成s,或者是squash
pick f5c61305 再次改進
s 06cb6a26 最終改進
# Rebase 5a46753b..06cb6a26 onto 5a46753b (2 commands)
然后就rebase完成了,三個提交被合并成一個了
接下來輸入最新的commit message,可以只寫一句。
最終push 得時候帶上 --force,覆蓋遠程分支,這樣提交記錄就很干凈了。
本文內(nèi)容基于廖雪峰的Git教程編寫