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