最近公司的代碼管理工具要從SVN轉(zhuǎn)到Git上,因此雖然之前用過(guò)Git,但是都是一些簡(jiǎn)單的推送提交,因此還是有必要進(jìn)行一些系統(tǒng)的學(xué)習(xí),這里做一下筆記,以備后詢(xún),且不定期更新。 關(guān)于SVN和Git的比較已經(jīng)有很多文章說(shuō)過(guò)了,就不再贅述,本文的重點(diǎn)是如何使用常用的Git命令進(jìn)行操作,冷門(mén)的就不說(shuō)了,且比較零散,系統(tǒng)的學(xué)習(xí)推介廖雪峰的Git教程。 聲明 下面用戶(hù)名都為 SHERlocked93 ,請(qǐng)自行修改成自己的用戶(hù)名
1. 概覽2. 修改2.1 暫存修改操作一覽 操作 | bash |
---|
創(chuàng)建stash | git stash | 查看 | git stash list | 應(yīng)用 | git stash apply stash@{ <num> } | 刪除 | git stash drop stash@{ <num> } | 還原上一個(gè)暫存并刪除暫存(如無(wú)conflict) | git stash pop |
如果在工作的時(shí)候出現(xiàn)了臨時(shí)需要解決的問(wèn)題,而你又不希望提交,那么有個(gè) stash 功能 在暫存后工作區(qū)會(huì)回退到最近的一個(gè)commit的狀態(tài),以便開(kāi)建新分支;比如我們修復(fù)bug時(shí),我們會(huì)通過(guò)創(chuàng)建新的bug分支進(jìn)行修復(fù),然后合并,最后刪除; 當(dāng)手頭工作沒(méi)有完成時(shí),先把工作現(xiàn)場(chǎng) git stash 一下,然后去修復(fù)bug,修復(fù)后,再 git stash pop ,回到工作現(xiàn)場(chǎng)。 2.2 撤銷(xiāo)修改還未提交到暫存區(qū)當(dāng)修改還沒(méi)有被 add 的時(shí)候,可以使用 git checkout -- filename.txt
來(lái)丟棄工作區(qū)某文件的修改,當(dāng)然也可以把后面的文件改成 * 來(lái)撤銷(xiāo)所有文件的修改。這是用倉(cāng)庫(kù)的文件覆蓋工作區(qū)的文件。 注意這里用的是 -- ,如果沒(méi)有這個(gè) -- 的話就變成切換分支了。 還未提交到倉(cāng)庫(kù)如果你的修改已經(jīng)被 add 到了暫存區(qū),但是還沒(méi)有被 commit ,那么可以使用 git reset HEAD filename.txt
git checkout -- filename.txt
首先用 reset 來(lái)把修改撤回到工作區(qū),再使用上面的 checkout 命令撤回工作區(qū)的修改。這里的 reset 相當(dāng)于 add 的反操作。 已經(jīng)提交到倉(cāng)庫(kù)則可以版本回退 git reset --hard 15zdx2s
這里的 --hard 表示強(qiáng)制回退,丟棄本地的修改。這個(gè)回退比較野蠻,該版本號(hào)之后的提交都將不可見(jiàn)。 撤銷(xiāo)之前某一個(gè)提交git revert 撤銷(xiāo)一個(gè)提交的同時(shí)會(huì)創(chuàng)建一個(gè)新的提交,這是一個(gè)安全的方法,因?yàn)樗粫?huì)重寫(xiě)提交歷史。但實(shí)現(xiàn)上和reset是完全不同的。它撤銷(xiāo)這個(gè)提交引入的更改,然后在最后加上一個(gè)撤銷(xiāo)了更改的新提交,而不是從項(xiàng)目歷史中移除這個(gè)提交。
相較于 reset , revert 不會(huì)改變項(xiàng)目歷史,對(duì)那些已經(jīng)發(fā)布到共享倉(cāng)庫(kù)的提交來(lái)說(shuō)這是一個(gè)安全的操作。其次 git revert 可以將提交歷史中的任何一個(gè)提交撤銷(xiāo)、而 reset 會(huì)把歷史上某個(gè)提交及之后所有的提交都移除掉,這太野蠻了。 相比 reset ,它不會(huì)改變現(xiàn)在的提交歷史。因此, revert 可以用在公共分支上, reset 應(yīng)該用在私有分支上。 合并commit如果已經(jīng) commit 了怎么辦,如果要撤回目前的 commit ,可以把它合并到上一個(gè) commit 中 git rebase -i HEAD~~
在出現(xiàn)的兩個(gè)提交信息的 pick 改為 fixup 3. 分支操作3.1 創(chuàng)建/查看/合并分支操作一覽 操作 | bash |
---|
查看分支 | git branch | 查看本地和遠(yuǎn)程分支 | git branch -a | 在target分支上創(chuàng)建分支,沒(méi)有則從當(dāng)前分支 | git branch <branch-name> <target-branch> | 創(chuàng)建并切換分支 | git checkout -b <branch-name> | 合并某分支到當(dāng)前分支 | git merge <branch-name> | 刪除分支,只能刪參與了合并的 | git branch -d <branch-name> | 強(qiáng)行刪除 | git branch -D <branch-name> | 刪除遠(yuǎn)程分支 | git push origin : <remote-branch-name> |
創(chuàng)建分支 # 創(chuàng)建新分支
git branch bug-fix
# 查看分支,-a查看本地和遠(yuǎn)程的分支,-r查看遠(yuǎn)程分支,-l或沒(méi)有只查看本地
git branch -a
# 切換到剛剛創(chuàng)建的分支
git checkout bug-fix
上面兩個(gè)步驟可以合并為 # 創(chuàng)建并切換到分支
git checkout -b bug-fix
如果修改一下本地文件之后在這個(gè)分支繼續(xù)培育一個(gè)版本之后,怎么去合并到主分支呢 git add *
git commit -m 'some change'
# 切換到主分支
git checkout master
# 合并分支
git merge bug-fix
# 刪除分支 (可選)
git branch -d bug-fix
如果master分支和新的分支都各自培育了版本,那么自動(dòng)合并通常會(huì)失敗,發(fā)生沖突 conflict ,此時(shí)需要打開(kāi)文件解決沖突之后 commit 一個(gè)版本以完成合并 git add *
git commit -m 'branch merge'
這里提一下, merge 的時(shí)候有幾個(gè)主要模式, --no-ff 、 fast-forward ,其中 fast-forward 是默認(rèn)的 fast-forward :在master開(kāi)始的新分支前進(jìn)了幾個(gè)版本之后如果需要merge回來(lái),此時(shí)master并沒(méi)有前進(jìn),那么這個(gè)模式就是把HEAD與master指針指向新分支上,完成合并。這種情況如果刪除分支,則會(huì)丟失分支信息,因?yàn)樵谶@個(gè)過(guò)程中并沒(méi)有創(chuàng)建commit。
--no-ff :關(guān)閉默認(rèn)的 fast-forward 模式,也就是在merge的時(shí)候生成一個(gè)新的commit,這樣在分支歷史上就可以看出分支信息。
3.2 遠(yuǎn)程倉(cāng)庫(kù)操作操作一覽 操作 | bash |
---|
克隆 | git clone <url> | 添加遠(yuǎn)程倉(cāng)庫(kù) | git remote add <name> <url> | 刪除遠(yuǎn)程倉(cāng)庫(kù) | git remote rm <name> | 拉取 | git pull <remote-branch-name> <local-branch-name> | 推送本地所有分支到遠(yuǎn)程 | git push --all origin | 推送到遠(yuǎn)程同名分支 | git push origin <local-branch-name> | 推送本地分支到遠(yuǎn)程master | git push origin <local-branch-name> : master | 把當(dāng)前本地分支推送并創(chuàng)建到遠(yuǎn)程 | git push origin | 檢出遠(yuǎn)程分支 | git checkout -b <new-local-branch-name> origin/ <remote-branch-name> |
關(guān)于各個(gè)分支,哪些需要推送呢 master 分支是主分支,因此要時(shí)刻與遠(yuǎn)程同步;
dev 分支是開(kāi)發(fā)分支,團(tuán)隊(duì)所有成員都需要在上面工作,所以也需要與遠(yuǎn)程同步;
bug 分支只用于在本地修復(fù)bug,就沒(méi)必要推到遠(yuǎn)程了,除非老板要看看你每周到底修復(fù)了幾個(gè)bug;
feature 分支是否推到遠(yuǎn)程,取決于你是否和你的小伙伴合作在上面開(kāi)發(fā)。
直接 clone 在github上創(chuàng)建一個(gè)新的項(xiàng)目之后,比如叫 learn-git ,那么可以直接 clone 下來(lái),注意創(chuàng)建的時(shí)候不要選擇 Initializethisrepositorywitha README ,我們要的是一個(gè)空的倉(cāng)庫(kù) git clone https://github.com/SHERlocked93/learn-git.git
這樣在本地就直接創(chuàng)建了一個(gè)空的文件夾 learn-git ,當(dāng)然里面有 .git 文件夾。也可以使用SSH地址來(lái)clone,速度會(huì)快一些,也不用每次推送都輸入口令,推介使用這種 git clone git@github.com:SHERlocked93/learn-git.git
添加一個(gè)文件 filename.txt 之后 git add filename.txt
git commit -m 'add filename.txt'
git push -u origin master
這樣就把本地新建的文件push到了遠(yuǎn)程倉(cāng)庫(kù) 本地與遠(yuǎn)程建立關(guān)聯(lián)如果已經(jīng)有了本地工程文件夾,如何分享到github遠(yuǎn)程倉(cāng)庫(kù)呢,當(dāng)然此時(shí)我們已經(jīng)在github上創(chuàng)建了一個(gè)新的空白項(xiàng)目,還是叫 learn-git ,在本地文件夾中 git init
# 關(guān)聯(lián)遠(yuǎn)程庫(kù)
git remote add origin git@github.com:SHERlocked93/learn-git.git
git push -u origin master
就可以了,如果你的遠(yuǎn)程倉(cāng)庫(kù)已經(jīng)有了提交,那么在 push 之前需要 # 允許不想干庫(kù)合并
git pull origin master --allow-unrelated-histories
git push -u origin master
先拉取遠(yuǎn)程分支,注意這里 --allow-unrelated-histories 允許兩個(gè)不想干的分支強(qiáng)行合并,再 push ;這樣在github的網(wǎng)站上還能看到commit記錄。 也可以強(qiáng)硬一點(diǎn)直接強(qiáng)行推送 # -f 強(qiáng)行推送
git push -u origin master -f
這樣本地倉(cāng)庫(kù)就直接把遠(yuǎn)程倉(cāng)庫(kù)覆蓋了,且github上也看不到歷史 commit 了,如果不想被同事槍擊的話,還是推介上一種做法。 同步遠(yuǎn)程倉(cāng)庫(kù)那么已經(jīng)clone的倉(cāng)庫(kù)如果希望同步原倉(cāng)庫(kù)新的提交怎么辦 # 從遠(yuǎn)程分支拉取代碼到本地
git pull upstream master
# push到自己的庫(kù)里
git push origin master
3.3 多人協(xié)作多人協(xié)作的工作模式通常是這樣: 首先,可以試圖用 git push origin<branch-name> 推送自己的修改;
如果推送失敗,則因?yàn)檫h(yuǎn)程分支比你的本地更新,需要先用git pull試圖合并;
如果合并有沖突,則解決沖突,并在本地提交; 沒(méi)有沖突或者解決掉沖突后,再用 git push origin<branch-name> 推送就能成功
從遠(yuǎn)程抓取分支,使用 git pull ,如果有沖突,要先處理沖突, add->commit->push 。如果 git pull 提示no tracking information,則說(shuō)明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒(méi)有創(chuàng)建,用命令 git branch--set-upstream-to<branch-name>origin/<branch-name> 。 4. 標(biāo)簽操作操作一覽 操作 | bash |
---|
查看所有標(biāo)簽 | git tag | 新建標(biāo)簽 | git tag <tagname> | 新建并制定說(shuō)明 | git tag <tagname> -m <message> <bash> | 查看標(biāo)簽說(shuō)明 | git show <tagname> | 刪除標(biāo)簽 | git tag -d <tagname> | 推送某個(gè)標(biāo)簽到遠(yuǎn)程 | git push origin <tagname> | 推送所有未推送到遠(yuǎn)程的本地標(biāo)簽 | git push origin --tags | 合并遠(yuǎn)程倉(cāng)庫(kù)的標(biāo)簽到本地 | git pull origin --tags | 刪除遠(yuǎn)程標(biāo)簽 | git push origin :refs/tags/ <tagname> |
如果要?jiǎng)h除遠(yuǎn)程分支,需要 # 首先刪除本地tag,假如tag是v0.9
git tag -d v0.9
# 再?gòu)倪h(yuǎn)程刪除
git push origin :refs/tags/v0.9
5. 提交格式type: feat: 新特性,添加功能 fix: 修改bug refactor: 代碼重構(gòu) docs: 文檔修改 style: 代碼格式修改, 注意不是 css 修改 test: 測(cè)試用例修改 chore: 其他修改, 比如構(gòu)建流程, 依賴(lài)管理.
網(wǎng)上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學(xué)習(xí)過(guò)程中的總結(jié),如果發(fā)現(xiàn)錯(cuò)誤,歡迎留言指出~ 推介閱讀: 廖雪峰 - Git教程 github實(shí)現(xiàn)本地倉(cāng)庫(kù)與遠(yuǎn)程倉(cāng)庫(kù)同步 圖解 Git 命令 git基本操作,一篇文章就夠了! 團(tuán)隊(duì)協(xié)作中的 Github flow 工作流程 git 命令大全
附件 Git常用命令速查表:
|