在使用git之前,一直用的是svn版本管理;與svn最大不同的是,git有兩個倉庫,一個是本地倉庫,一個是服務器上共享的倉庫;本地倉庫是每個開發者自己獨有的,即使commit提交也只是提交到本地倉庫;這只是git流行起來的一個優勢之一,另外linux作者開發的這套版本管理工具,很接地氣,也是流行起來的一大亮點。扯了這么多沒用的,言歸正卷,那么在日常開發工作中,哪些git命令是我們常用到的呢?下面就說說幾個常用命令的常用場景,至於這些命令詳細使用就不在本文討論之內。
1、git命令別名
使用過git的都知道,git的有些命令名有些長,每次在使用改命令時都要輸入這些,尤其是一些命令語句;怒長的一串文字字符串打起來很費勁,開發者也很不爽;這時我們的git alias功能可以費墨登場了。下面是本人的一些常用命令的alias配置:
命令 | 別名 |
commit | ci |
checkout | co |
status | st |
merge origin/master | mom |
注意:以上git命令別名的設置是在計算機用戶目錄下.gitconfig文件全局設置的,這樣所有git分支都能運用設置的別名。當然,根據不同開發者的個人喜好,可以有自己的別名設置;
2、git checkout
這個命令用於檢出某個分支、提交或者對應的某個分支、提交的文件。根據不同的參數來檢出不同的內容;那么其常用場景如下:
- git checkout . 用暫存區的內容覆蓋當前工作區內容,那么可以達到用暫存區的內容來撤銷本地分支的修改
某些情況下,想在當前分支中做一下測試,這時修改了當前分支的多個文件,測試過后要撤銷對當前分支的變更,這時可以使用git checkout . 命令;
注意:使用該命令需要注意一點:本地分支所有文件的變更都會被撤銷 - git checkout -b newBranchName origin/master 基於master創建一個新分支,並切換到新分支上
避免了git branch完成此功能需要多執行一步:
git branch newBranchName origin/master
git checkout newBranchName - git checkout - 切換到 切換到當前分支之前的分支
使用場景:開發本地創建多個分支來完成不同的需求,這時可能需要來回切換不同的分支,如在A分支開發時,提測的B分支有bug,qa要讓fixed,這時就切換到B分支屁顛屁顛的修bug,完事之后要切換到A分支,此時可以使用快捷命令 - git checkout commitId/branchName -- path 用指定的提交id或者分支的某個文件來替換本地與其對應的文件,達到該文件的內容變更的撤銷
使用場景:由於某種原因,在眾多的文件變更中,只撤銷某個指定文件的內容變更
3、git stash
該命令用於暫存本地文件的修改。
某天,開發者在一個分支上開發某個需求,突然這種自我happy的開發方式被打斷,某個提測的分支有bug需要馬上修復;擦,本地的代碼還沒有提交呢,但是又不想因臨時的提交本地代碼導致如何描述臨時提交的描述。於是乎就可以使用git stash來存取本地變更的代碼;然后切換有bug的分支解決問題,最后回到本分支使用git stash pop即可復現之前沒有提交的本地變更代碼;該命令是不是用起來很爽。
但是,使用該命令需要注意以下兩點:
- git stash只是保存已經git add過的文件變更,只要暫存過的文件都會被保存;那么本地新增的文件,必須使用git add命令之后才會被保存,否則提示你需要將新增文件要暫存;
- 暫存的分支需要使用git stash pop恢復;但是若多次git stash,需要准確記住某個分支的對應的保存位置,否則容易搞錯;可以使用 git stash list來查看;
4、git revert
用於撤銷某次提交的變更內容。這個revert與webstrom等IDE中提供的revert掉git的某些文件不同,后者其實最終還是利用git checkout來實現的。
該命令的最大場景是:代碼發布上線后,由於某種原因需要代碼回滾,這時基於當前分支發布的分支在線上代碼回滾后merge master時,本地新開發的需求代碼丟失了,因為回滾到上線之前的代碼,這個時候還不存在回滾掉的代碼;怎么恢復merge掉的代碼呢,這時就需要git revert了,具體步驟如下:
- 通過git reflog查看回滾生成的commit,如下圖本地曾經回滾過的日志,e103c47是回滾時新生成的提交點
- 使用命令 git revert e103c47即可恢復merge掉的代碼
5、git reset
該命令用於重置指定區域的內容,可以操作提交,也可以操作文件;該命令的三個參數--hard、--mixed、--soft表示重置的范圍,這個命令也是最常用的命令之一;
使用該命令得記住一點,它會對git的提交歷史做修改,可能會刪掉一些歷史提交點導致不能恢復。
- git reset [--mixed] commitId 用commitId的內容重置暫存區的內容,工作區內容不會被覆蓋,這樣可達到撤銷暫存區的變更;
場景:某次變更的代碼一不留意用git add添加到暫存區,但是想要撤銷暫存區的內容而不會導致本地工作區代碼丟失,這時可以使用git reset HEAD - git reset --hard commitId 用commitId的內容重置暫存區和工作區的內容
場景:在某次升級某個穩定性不確定但是功能全面的框架,使用包管理機制下載最新的框架源碼,開發一段時間后發現有很大問題,但是這時代碼已經git add到暫存區,想要撤銷掉工作區和暫存區的內容變更時,就可以使用git reset --hard HEAD - git reset commitId -- path 用指定commitId的文件內容替換掉暫存區對應文件,工作區的不便;
注意:該操作不會修改git的提交歷史
6、git branch
用於創建、顯示分支等與分支相關的命令,工作中常用到的情況:
- git branch branchName origin/master 基於master創建一個分支
這種情況創建的分支要進行完整的開發,過程有些繁瑣,需要:
git checkout branchName //切換到新建的分支上 git push //將當前分支推送服務器 git branch -u origin HEAD //建立當前分支與服務器同名分支的上傳流
但是在實際中,個人比較傾向於下面一種,只需兩步即可:
git checkout -b branchName origin/master git push -u origin HEAD
- git branch -vv 查看本地分支的upstream的對應情況,一定要確保本地分支與服務器上分支的對應情況,因為不單獨設立對應情況,新建分支默認與master是對應關系
- git branch -remote 查看的是本地倉庫的所有分支
- git branch -D branchname 刪除本地分支
注意:需要切換到其他分支進行其操作,不能在當前分支刪除當前分支,這是不允許的
7、git push
用於與服務器倉庫同步代碼,該命令的用法不做贅述,該命令的一個常用情況就是刪除服務器端某個指定的分支,命令如下:
git push origin 空格:remote_branch_name
8、git rm
該命令用於刪除分支中的文件,他可以只刪除暫存區的文件,也可以同時刪除暫存區和工作區的文件,參數不同,決定刪除的文件范圍也不同,具體如下:
git rm --cached filename //刪除暫存區的某個文件,工作區的不會刪除 git rm filename //同時刪除暫存區和工作區的該文件
git rm filename的場景:為滿足某次需求,新增了一些代碼文件,在開發中可能不小心將某個無用的新文件加到工作區而被git add到暫存區,這時需要同時刪掉暫存區和工作區的該文件;
9、git commit
用於提交暫存區代碼到本地倉庫;說一下git commit --amend選項
git commit --amend 的使用場景:某次需求開發提交中,由於某種原因導致提交的結果不是期望的,需要重新提交,但是又不希望前一次的提交使git提交歷史樹變長,那么可以使用git commit --amend來用暫存區的內容修正前一次的提交。 如果不使用帶--amend的提交,結果是git提交歷史樹會變長。git commit --amend的原理圖如下:
10、git blame
在多人協作開發的項目中,想要知道某個文件的歷史改動情況,可以使用該命令來完成,具體如下:
git blame -L line1, line2 file
上面是查看file文件的第line1行到line2行代碼的改動情況,如下圖是查看本地某個文件的192到193行的改動情況,看出是adam23有最新改動
上面介紹的都是自己用的比較頻繁的git命令和對應的場景,當然有些情況不一定值得借鑒,或者還有不妥的地方,這些都希望大家批評指正!!
11、.gitignore詮釋
使用.gitignore時,可能會發生這樣一種情況:明明在.gitignore中設置了忽略某個文件,可以用git status查看時還是會追蹤其變化*;遇到這種情況,如果想當然的認為配置到`.gitignore`中的文件不會被追蹤,那么可能是你對.gitignore的有誤解。
那么.gitignore的具體理解是什么樣呢,具體有兩個方面需要注意:
- .gitignore只會忽略從未在git倉庫中維護的文件,即*自文件添加以后,從未 add 及 commit 過的文件*;這時`.gitignore`中配置的文件是有效的,即git不會追蹤其變化。
- 已經在git倉庫維護過的文件,即使在`.gitignore`中配置不要追蹤其變化,一旦文件變化git還是會追蹤的。
通俗的說,就是`已經維護起來的文件,即使加上了gitignore,也無濟於事`
了解上面的情況,才算是對.gitignore真正的理解。那么問題來了:**如何忽略對git倉庫中已維護文件的變化的追蹤呢?**
答案是使用:git update-index --assume-unchanged path。例如git倉庫中已維護logs目錄,想忽略該目錄下的所有.js文件的變化,可以這樣:
git update-index --assume-unchanged logs/*.js
具體可以參考這里