Git 命令行操作
全文結(jié)構(gòu):
1)倉(cāng)庫(kù)概念
首先從總體上看,git的存儲(chǔ)、操作:
主要涉及到四個(gè)關(guān)鍵點(diǎn):
工作區(qū)(workspace):本地電腦存放項(xiàng)目文件的地方,比如learnGitProject文件夾;
暫存區(qū)(Index/Stage):在使用git管理項(xiàng)目文件的時(shí)候,其本地的項(xiàng)目文件會(huì)多出一個(gè).git的文件夾,將這個(gè).git文件夾稱之為版本庫(kù)。其中.git文件夾中包含了兩個(gè)部分,一個(gè)是暫存區(qū)(Index或者Stage),顧名思義就是暫時(shí)存放文件的地方,通常使用add命令將工作區(qū)的文件添加到暫存區(qū)里;
本地倉(cāng)庫(kù)(Repository):.git文件夾里還包括git自動(dòng)創(chuàng)建的master分支,并且將HEAD指針指向master分支。使用commit命令可以將暫存區(qū)中的文件添加到本地倉(cāng)庫(kù)中;
遠(yuǎn)程倉(cāng)庫(kù)(Remote):不是在本地倉(cāng)庫(kù)中,項(xiàng)目代碼在遠(yuǎn)程git服務(wù)器上,比如項(xiàng)目放在github上,就是一個(gè)遠(yuǎn)程倉(cāng)庫(kù),通常使用clone命令將遠(yuǎn)程倉(cāng)庫(kù)拷貝到本地倉(cāng)庫(kù)中,開發(fā)后推送到遠(yuǎn)程倉(cāng)庫(kù)中即可;
2)分支概念
1)分支介紹:
develop分支(唯一):用于平時(shí)開發(fā)的主分支,并一直存在,永遠(yuǎn)是功能最新最全的分支。
feature分支(N個(gè)):用于開發(fā)新的功能的分支,一般是多個(gè)員工一人一個(gè)feature遠(yuǎn)程分支。
release分支:用于發(fā)布準(zhǔn)備的專門分支。
master分支(唯一):最為穩(wěn)定、隨時(shí)可發(fā)布的代碼;所有在 master 上的提交都必要要有 tag ,方便回滾。
hotfix分支:用于修復(fù)線上代碼的 bug
2)分支關(guān)系:
develop和master是2個(gè)主要分支,這兩個(gè)都是唯一的;
其他的3種分支都是從這2個(gè)分支派生出來(lái)的:
feature從develop拉出,并回到develop
release從develop拉出,并推送到develop+master兩個(gè)分支(保證同步)
hotfix從master拉出,并推送到develop+master兩個(gè)分支(保證同步)
3)特性總結(jié):
生命周期:
feature和hotfix是臨時(shí)的
其他3個(gè)都是長(zhǎng)期存在
直接開發(fā):
從不:master、release
不建議:develop
直接:feature、hotfix(和臨時(shí)對(duì)應(yīng))
一、基礎(chǔ)流程
首次需:
0. git init初始化新倉(cāng)庫(kù)(init 好像沒啥用)
1. 到代碼文件夾,右擊 Git Bash Here,打開到本文件路徑
2.git clone + GitHub網(wǎng)頁(yè)上Repository復(fù)制下來(lái)的URL
3. 此時(shí)是遠(yuǎn)程分支是origin/master(origin層次下的master分支);本地分支是默認(rèn)的master;需要切換遠(yuǎn)程分支和本地分支:
git checkout-b jqy-local-dev(本地分支名)origin/dev(遠(yuǎn)程分支名)
(如果沒有這一步的操作,就會(huì)從master拉取,因?yàn)镾SH的url只有一個(gè))
3.1先用 git branch -a 查看所有本地+遠(yuǎn)程分支
3.2 切換分支
注意上圖中本地分支已經(jīng)切換,origin/dev是根據(jù)需要選擇的遠(yuǎn)程分支,遠(yuǎn)程分支改變后,本地文件會(huì)由origin/master這個(gè)遠(yuǎn)程分支變?yōu)槟氵x擇的遠(yuǎn)程分支
(ps: 將本地分支和遠(yuǎn)程分支關(guān)聯(lián)的操作一般只用于拉取的時(shí)候,而后面就不用管這個(gè)關(guān)聯(lián)了,因?yàn)間it push origin jqy 這個(gè)指令一般不用,都不會(huì)原路推到代碼來(lái)源如dev遠(yuǎn)程分支,而是push到自己的遠(yuǎn)程分支,然后MR等待評(píng)審再合并到需要的分支)
后續(xù):
不斷編碼修改...
4. cd到新文件夾中,Git Bash
5.git add . (注意" . "不能省略,此操作是把文件夾下面新的文件或修改過的文件添加進(jìn)來(lái),如果有的文件之前已經(jīng)添加了,它會(huì)自動(dòng)省略)
6.git commit -m "提交信息"(提交的信息是你的項(xiàng)目說明)
7.(配置好用戶名、郵箱)
8.git push origin master
git push [remote-name] [branch-name]
(此操作目的是把本地倉(cāng)庫(kù)push到github上面,此步驟需要你輸入登錄github上的帳號(hào)和密碼)
(一般團(tuán)隊(duì)開發(fā)都用 git push origin jqy:jqy001這樣推到自己的遠(yuǎn)程分支,然后提交MR;而不是直接push就完事)
git push originjqy:jqy001本地分支提交到遠(yuǎn)程分支
(9.) 如果push的時(shí)候顯示沖突(有人改了對(duì)應(yīng)的遠(yuǎn)程分支),就先pull一下:
git pull origin jqy001
對(duì)比沖突,解決后再push
10.然后在網(wǎng)頁(yè)中Submit MR,比如從jqy001==>dev
等待代碼審核即可...
二、分支管理
git branch查看本地分支;
git branch -a查看所有分支(包括遠(yuǎn)程)
上方是本地分支區(qū),下方origin一堆是遠(yuǎn)程分支;箭頭指向的是當(dāng)前本地分支、遠(yuǎn)程分支
git checkout -b[branchname] 創(chuàng)建+切換 分支
git branch dev 創(chuàng)建分支(這個(gè)一般用不上)
git checkout dev 切換分支(此處的dev可以為git reflog的七位數(shù)字)
git branch -d[local-branch-name] 刪除分支(本地)
git branch -r -d[remote-branch-name] 刪除(遠(yuǎn)程remote)分支
修復(fù)上一個(gè)版本的bug:
1. git log找到bug版本的版本號(hào)
2.git branch 1db3731將HEAD移動(dòng)到bug版本
3.git branch -b myfixbug然后開始在此分支修改bug
4.等到master里面到下一個(gè)版本上線之前,合并myfixbug
最好看著IDEA中的版本線狀圖===》》》
順便學(xué)習(xí)Github/CodeHub團(tuán)隊(duì)開發(fā)策略(分支策略)總結(jié)下來(lái)
git push origin master //push到origin的master分支
git push origin dev //push到origin的dev分支
git remote -v查看連接SSH的url (遠(yuǎn)程庫(kù)的默認(rèn)名稱是origin)
git branch -v
git branch -vv
顯示local分支對(duì)應(yīng)的遠(yuǎn)程分支
設(shè)置origin:
三、團(tuán)隊(duì)開發(fā) - MR提交
在團(tuán)隊(duì)合作軟件開發(fā)方面,一般有master分支和develop分支,
開發(fā)者先發(fā)送merge request請(qǐng)求到develop上,然后通過 項(xiàng)目管理者review之后,才會(huì)merge到master分支上。
Merge Request
(建議在IDEA里面進(jìn)行,因?yàn)榉奖銓?duì)照修改的內(nèi)容):
git branch -b jqy 建自己的本地分支
git add 需要修改的文件(最好不要用git add . 因?yàn)檫@樣會(huì)add上一些無(wú)用的東西)
git commit (提交到自己的本地)
git pull origin jqy001 (與origin中jqy001這個(gè)遠(yuǎn)程分支進(jìn)行對(duì)比,修復(fù)沖突,并提交需要上線的文件)
git push originjqy:jqy001 本地分支提交到遠(yuǎn)程分支
成功的話,然后在網(wǎng)頁(yè)中Submit MR
(然后就會(huì)由管理員審核MR并提交UAT測(cè)試環(huán)境。。)
Merge Request(這種方法一般在push的時(shí)候會(huì)被卡主)
1)git checkout -b xxx(xxx是新建分支的名字,如feature_i)
2) git add . git commit -m "..." git push originxxx //在自己的xxx分支的操作
3.1)git checkout master git mergexxx git push originmaster//切換到master進(jìn)行合并【命令行版】
3.2) (一定確保第2步有g(shù)it push originxxx)然后在gitlab界面進(jìn)行merge request的信息填寫 【GUI版,適用于代碼審核】
四、解決沖突
git mergedev // 一般將dev分支的修改merge到master分支上
merge的時(shí)候,如果有同時(shí)修改的內(nèi)容, 就發(fā)生沖突(此時(shí)無(wú)法自動(dòng)merge),需要查看conflict然后手動(dòng)合并。
一開始兩個(gè)不同的分支同時(shí)修改master的readme文件:
第一個(gè)merge的不會(huì)出問題,
第二個(gè)merge時(shí)候:
在git mergefeature_1之后,查看feature_1的文件,會(huì)顯示比對(duì)信息:
手動(dòng)修改readme文件(不用切換到feature_1分支),
然后在master分支上面,add+commit
然后直接 git push origin master就好了(可以在gitlab 網(wǎng)頁(yè)GUI上面直接看一下驗(yàn)證):
【另一種方式push】
第二個(gè)push出現(xiàn)沖突時(shí):
然后git pull
修改、git add、git commit
然后再push就好
五、回退版本(時(shí)光穿梭機(jī))
git status 查看工作目錄、暫存區(qū)的狀態(tài)
git diff 查看修改內(nèi)容(Git跟蹤并管理的是文件的修改,而非文件本身)
git diff 詳細(xì)命令: https://www.jianshu.com/p/80542dc3164e
git log查看日志(一次次commit修改情況,注意是以commit為粒度)
(git log-p 可看到具體修改內(nèi)容。按Enter向下閱讀)
1)已經(jīng)commit之后
git reset --hardHEAD~1 回退1個(gè)提交(徹底回退,沖掉回退的信息)
git reset --softHEAD~1 回退1個(gè)提交+保留代碼修改信息
git reset --hardd311cd2 ==》先用git reflog查看各個(gè)版本的 commit id(如d311cd2)進(jìn)行自由回退 (很好用!)
2)已經(jīng)add,但沒有commit(錯(cuò)誤還在 stage暫存區(qū))
兩步操作:
git reset HEAD [filename]
git checkout -- [filename]
3)還沒有add(錯(cuò)誤還在 工作區(qū))
只需要一步:
git checkout -- [filename]
(這樣操作的粒度比較小;reset的話,粒度比較大;因?yàn)橐话闶且淮蝐ommit是一到多次add的總和)
分析下粒度:
多次add,一次commit;
多次commit,一次push;
所以:
commit后的reset --hard 序號(hào)《==》1~n次的commit的粒度
add后的reset HEAD《==》回退到上次commit后的狀態(tài),相當(dāng)于1~n次的add的粒度
add前的 checkout -- [filename] 《==》回退到上次add后的狀態(tài),相當(dāng)于1次add內(nèi)的粒度
詳細(xì)說明git reset:
git reset --hard HEAD^ 硬回退一步
(此時(shí)本地回退了,但是遠(yuǎn)程沒有回退;如果需要遠(yuǎn)程也回退,就要git push origin xxx再提交一下)
git reflog查看各個(gè)版本的 commit id(如d311cd2)
git reset --hardd311cd2根據(jù)后面的commit -m "..."信息,找到對(duì)應(yīng)的id,進(jìn)行自由回退 (很好用!)
六、忽略文件.gitignore
1)規(guī)則
/ //表示目錄 * //匹配 任意個(gè)字符 ? //匹配 一個(gè)字符 [ ] // 正則匹配 一個(gè)字符 ! //表示忽略匹配
2)示例
# 此為注釋 – 將被 Git 忽略 *.log #表示所有的 .log文件(也包括子目錄里的) *.iml *.ipr *.iws *.txt # 忽略所有 .txt 結(jié)尾的文件 !Readme.txt # 但 Readme.txt 除外 /TODO # 僅僅忽略項(xiàng)目根目錄下的 TODO 文件,不包括 subdir/TODO /node_modules hello[0-9].txt .settings/ # 忽略settings文件里的全部 .idea/ .vscode/ target/ .gradle /config build/ # 忽略 build/ 目錄下的所有文件 doc/*.txt # 會(huì)忽略 doc/notes.txt 但不包括 doc/server/arch.txt /fd1/* #忽略根目錄下的 /fd1/ 目錄的全部?jī)?nèi)容; fd1/* #忽略目錄 fd1 下的全部?jī)?nèi)容;注意,不管是根目錄下的 /fd1/ 目錄,還是某個(gè)子目錄 /child/fd1/ 目錄,都會(huì)被忽略;
想把某些目錄或文件加入忽略規(guī)則,按照上述方法定義后發(fā)現(xiàn)并未生效,原因是.gitignore只能忽略那些原來(lái)沒有被track的文件,如果某些文件已經(jīng)被納入了版本管理中,則修改.gitignore是無(wú)效的。那么解決方法就是先把本地緩存刪除(改變成未track狀態(tài)),然后再提交:
gitrm-r--cached.
gitadd.
gitcommit-m'update.gitignore'
PS:理解CRLF / LF
CRLF回車換行。
Windows換行方式 CRLF==carriage return line feed
LF換行。
Linux&Unix換行方式 LF== line feed
本來(lái)在自己的 Ubuntu 系統(tǒng)上跑的很好,覺得沒bug就提交了。然而,同事使用的是Windows系統(tǒng),他編譯之后怎么跑都不正常。
在Windows系統(tǒng)上換行符是CRLF, 兩個(gè)字符,只刪除
是不夠的。所以在讀取文件的時(shí)候一定要小心跨平臺(tái)。
Git 提供了一個(gè)名為core.autocrlf的配置,可以自動(dòng)完成標(biāo)準(zhǔn)化與轉(zhuǎn)換。它的設(shè)置方式如下:
git config --global core.autocrlf [true | input | false] # 全局設(shè)置 git config --local core.autocrlf [true | input | false] # 針對(duì)本項(xiàng)目設(shè)置
true:CRLF <=> LF
input:CRLF => LF
false:不變
注意:
CRLF 與 LF 混合的文本文件不受此配置控制。
Git 安裝后默認(rèn)為 false
使用 Windows 系統(tǒng)的開發(fā)者設(shè)置:
git config --global core.autocrlf true
使用 Linux/MacOS 的開發(fā)者設(shè)置:
git config --global core.autocrlf input
ps:IDEA界面化Git操作
更多內(nèi)容參見:《Git -- IDEA界面操作》
命令行操作是git的根基,在此基礎(chǔ)上的 IDEA界面操作,功能更加可視化、易于理解。
參考 git使用教程(有詳細(xì)實(shí)例):https://zhuanlan.zhihu.com/p/30044692
git基本操作(精簡(jiǎn)手冊(cè)):https://juejin.im/post/6844903598522908686
廖雪峰git:https://www.liaoxuefeng.com/wiki/896043488029600
最后去練習(xí)吧:https://learngitbranching.js.org/?locale=zh_CN
總結(jié)
- 上一篇: 牛哪里的肉最好吃 揭秘牛肉的最佳部位?
- 下一篇: 要买奶茶给女孩子她说不用我不喝你自己买着