緣起
之前按照教程系統(tǒng)學(xué)習(xí)了git, 自以為掌握, 但是在實際工作中卻發(fā)現(xiàn)許多超出普通教程的操作需求.
忽略某些文件
情境
某些文件不需要納入git進行管理, 比如緩存文件, 比如用于本地測試的設(shè)置
解決
創(chuàng)建一個.gitignore
文件, 列出需要忽略的文件, 其配置語法是:
- 以斜杠
/
開頭表示目錄; - 以星號
*
通配多個字符, 比如*.DS_Store
表示忽略所有以.DS_Store
結(jié)尾的文件; - 以問號
?
通配單個字符; - 以方括號
[]
包含單個字符的匹配列表; - 以嘆號
!
表示不忽略某個特定文件或目錄;
注意
- .gitignore是從上到下進行規(guī)則匹配的, 也就是說如果前面的規(guī)則匹配的范圍更大, 則后面的規(guī)則將不會生效;
- 設(shè)置"文件夾忽略"時要注意:
/myDir/*
表示忽略根目錄下的"myDirname"文件夾, 如果是myDir/*
則表示只要文件夾名字是"myDirname", 不管它是在根目錄, 還是其它層次(比如/parentDir/myDir/*
)都會被忽略! - 如果在開發(fā)過程中, 需要修改忽略列表, 會發(fā)現(xiàn)沒有生效, 那是因為
.gitignore
對已經(jīng)被 track 的文件是無效的登颓,換句話說, 如果文件已經(jīng)被納入 git 版本管理顶瞒,則修改.gitignore
是無效的.
解決辦法是先把本地緩存刪除, 使其變成 "未 track" 的狀態(tài), 然后再提交. 注意, 執(zhí)行這項操作要非常謹慎! 因為很可能發(fā)生這種情況: 如果之前設(shè)置了錯誤的忽略規(guī)則, 因為沒有生效, 所以沒有對項目造成影響, 但是讓這些錯誤規(guī)則真的生效, 會破壞項目! 第一, 要反復(fù)檢查 '.gitignore' 規(guī)則; 第二, 執(zhí)行這項操作后, 在提交到遠程倉庫之前, 要git status
查看被影響的文件是否符合預(yù)期.
git rm -r --cached .
git add .
git commit -m '由于 .gitignore 無法忽略已經(jīng) track 的文件, 所以刪除緩存重新提交, 使 .gitignore 生效'
解決辦法是把本地緩存中打算忽略但是已經(jīng)被 track 的文件刪除, 使其變成 "未 track" 的狀態(tài).
git rm --cached <file>
暫存工作區(qū)的內(nèi)容
情境
在dev分支工作到一半, 但是需要緊急修復(fù)一個bug(需要從master中新建一個bug分支), 但是dev分支的工作進行到一半, 還沒到commit提交的程度.
解決
- 在dev分支中使用
git stash
將未完成的工作暫存起來(stash在英文中是"隱藏"的意思); - 按照正常的步驟去修復(fù)bug -- 從master中新建一個bug分支, 然后修復(fù), 修復(fù)完后合并到master分支;
- 切換回dev分支, 使用
git stash pop
就可以將之前隱藏的修改恢復(fù)到dev分支了;
注意
如果是新增文件, 不能直接git stash
, 必須先git add
添加到緩存區(qū)(納入git版本管理)才可以.
讓 Git 跟蹤重命名的文件
情境
直接修改文件名, 會導(dǎo)致 Git 中的記錄是"刪除文件, 而重命名后的文件被當(dāng)作新增的文件".
那么如何讓 Git 跟蹤重命名的文件, 保持記錄的可追溯?
解決
使用 git mv
命令, 即 "move/移動"命令
比如, 要將 PosterModel.php
修改為 Poster.php
:
git mv src/models/PosterModel.php src/models/Poster.php
拉取遠程倉庫的特定分支
情境
需要拉取公司遠程倉庫中的某一個特定分支.
解決
- 執(zhí)行
git fetch
, 將遠程倉庫的所有分支信息獲取到本地; - 執(zhí)行
git checkout -b local_branch_name origin/remote_branch_name
將該遠程分支("origin/remote_branch_name")映射到本地名為"local-branchname"的分支; - 之后再執(zhí)行拉取
git pull origin local-branchname
(PS. 執(zhí)行git fetch
后, 可以使用git branch -r
查看拉取到本地的所有分支名稱)
刪除遠程倉庫的分支
情境
因為 Git "分支"功能強大易用, 也間接導(dǎo)致公司遠程倉庫的分支非常多, 而其中大部分分支是已經(jīng)開發(fā)完畢, 可以廢棄的.
解決
git push origin --delete <branchName>
, 比如git push origin --delete dev_msg
PS. 刪除 tag 也是類似的: git push origin --delete <tagName>
克隆時的文件夾層次問題
情境
git clone
時會以項目名稱建立文件夾, 比如公司的遠程倉庫名稱是"OwnerName/RepoName", 克隆后會在當(dāng)前文件夾新建一個"RepoName"的文件夾.
如何把代碼直接放在根目錄, 而不是新建并且放在"RepoName"文件夾下呢?
解決
在git clone
后面加上./
, 比如git clone https://git.oschina.net/xxxx/xxxx.git ./
commit時如何書寫message
情境
(如題)
(部分)解決
暫時還沒有形成系統(tǒng)的解決辦法, 不過有2個心得:
團隊協(xié)助時, 用戶名稱要修改成自己的名字, 方便別人識別;
之前使用 "patiencing" 做為 git 上的用戶名, 在閱讀 git 記錄時發(fā)覺識別度很低, 可以預(yù)見別人看到這個名字時的困惑 -- 查看 git 記錄時無法第一時間得知是誰修改了代碼.
之后改為了自己的真實名字git config --global user.name yourrealname
(PS. 如果你不想全局修改, 只要去掉--global
, 也就是執(zhí)行git config user.name yourname
, 則只修改當(dāng)前 git 倉庫的用戶名)-
在 commit 的 message 頭部添加"代碼修改范圍"和"代碼修改類別", 方便別人和自己查閱 Git 記錄時能夠很快理解代碼修改的目的.
個人使用并且試驗有效的分類是:-
[@優(yōu)惠券#修補]
(表示本次提交是針對"優(yōu)惠券",任務(wù)類型是修補Bug,而 message 描述建議是對 Bug 的具體情形) -
[@優(yōu)惠券#排版]
(用于調(diào)整縮進等排版, 方便閱讀; 不涉及功能性變動) [@優(yōu)惠券#新增]
[@優(yōu)惠券#刪除]
[@優(yōu)惠券#修改]
-
[@優(yōu)惠券#體驗]
(優(yōu)化用戶體驗) -
[@優(yōu)惠券#優(yōu)化]
(優(yōu)化代碼, 重構(gòu), 刪除冗余代碼)
-
撤銷之前的操作
情境
后悔, 需要撤銷之前的操作.
解決
- 想要撤銷"工作區(qū)"中的修改
可以使用git checkout -- /path/file
來撤銷指定文件的工作區(qū)的修改, 恢復(fù)到上一次commit的狀態(tài)
(PS. 可以執(zhí)行git checkout -- .
來撤銷當(dāng)前工作文件夾的所有變動) - 想要撤銷已經(jīng)
add
提交到了緩存區(qū)的修改
先用git reset HEAD /path/file
將文件從緩存區(qū)重新放回工作區(qū)
再執(zhí)行git checkout -- /path/file
撤銷該文件的修改 - 想要修改
commit
的"message"
如果commit
后沒有進行新的commit
, 可以直接使用git commit --amend
對上一次的message進行修改 - 撤銷意外添加到緩存區(qū)的文件
類似上文中在開發(fā)過程中更新".gitignore"的操作:
git rm --cached -r dir
作用是刪除緩存區(qū)中的文件
(PS. --cached
表示"git的緩存", -r
等于"recursive/遞歸", 表示遞歸刪除文件夾中的所有文件)
查看指定文件的版本記錄
情境
想查看某個指定文件的修改記錄
解決
git log <file>
比如
git log config/database.php
題外
之前從事的是傳統(tǒng)行業(yè)的設(shè)計工作, 使用"給文件名添加版本或者日期 / 文件封面的版本記錄以及扉頁的版本更新說明 / 云霧線 / 公用盤 ..."來進行版本控制 (大型工程公司也有在使用專業(yè)的文件管理系統(tǒng)來解決版本控制問題; 之前和英國的工程公司合作, 對方使用的就是這種系統(tǒng), 我的體會就是"異常嚴謹, 同時操作反人性, 異常難用")
現(xiàn)在轉(zhuǎn)行到程序員, 用著 git 這個版本管理工具, 回首以前面對版本控制的痛苦, 不得不感慨"程序員這個行業(yè)雖然辛苦, 但是更容易享受到工作帶來的"心流 flow ".
參考文章
StackOverflow - How to make Git “forget” about a file that was tracked but is now in .gitignore?
文章歷史
- 2016.12.14 (第一次發(fā)布)
- 2017.03.04 增加"刪除遠程倉庫的分支"
- 2017.03.09 增加對"刪除 git 緩存重新提交, 使中途修改的 .gitignore 生效"的操作的風(fēng)險提醒
- 2017.03.09 修改"使中途修改的 .gitignore 生效"的操作, 從刪除全部緩存, 更新為刪除指定文件的緩存, 杜絕風(fēng)險
- 2017.03.10 增加"查看指定文件的版本記錄"
- 2017.03.17 增加"讓 Git 跟蹤重命名的文件"
- 2017.04/30 修改"commit時如何書寫message", commit message 頭部增加"范圍"和"類別"
- 2017.05.03 修改潤色
如果你覺得我的文章對你有用, 請打個"喜歡", 或者給些改進的建議 _