項(xiàng)目開發(fā)中g(shù)it是非常重要的,它可以有效关摇、高速地處理從很小到非常大的項(xiàng)目版本管理。
資料:
- 廖雪峰git教程: https://www.liaoxuefeng.com/wiki/896043488029600
- git 筆記: https://github.com/Zhangguoliu/learn-git/blob/master/learngit-note.md
- git 教程: https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-總結(jié)
- git 命令的理解: https://www.yiibai.com/git/git_fetch.html
- git 在線學(xué)習(xí): https://learngitbranching.js.org/?demo
- 了解git flow 協(xié)作開發(fā)理念 : https://www.cnblogs.com/cnblogsfans/p/5075073.html!
項(xiàng)目開發(fā)常用命令
可以設(shè)置當(dāng)前倉(cāng)庫(kù)的 用戶和郵箱
git config --local user.name 'xxx';
git config --local user.email 'xxx';
設(shè)置全局的倉(cāng)庫(kù)大的用戶名和郵箱
git config --global user.name 'xxx';
git config --global user.email 'xxx';
在github提交代碼后貢獻(xiàn)如果沒有被記錄碾阁,有可能就是你全局或者當(dāng)前的git倉(cāng)庫(kù)的用戶名和郵箱不是github的用戶名和郵箱输虱。
如果這個(gè)命名存在也可以直接覆蓋修改,還可以替換git config中已有的郵箱
$ git config --global --replace-all user.email "輸入你的郵箱"
$ git config --global --replace-all user.name "輸入你的用戶名"
保存密碼: 如果沒有設(shè)置ssh 可以通過保存密碼的方式來跳過輸入密碼這個(gè)步驟
git config credential.helper store
git stash: https://www.cnblogs.com/zndxall/archive/2018/09/04/9586088.html
本地主分支 :
origin/HEAD -> origin/master
表示默認(rèn)分支查看提交詳細(xì)信息:
git show
git status
:命令用于顯示工作目錄和暫存區(qū)的狀態(tài)。使用此命令能看到那些修改被暫存到了, 哪些沒有, 哪些文件沒有被Git tracked
到脂凶。git status
不顯示已經(jīng)commit
到項(xiàng)目歷史中去的信息宪睹。 一般紅色的沒有被追蹤到,綠色的是已經(jīng)add后的蚕钦, 意思就是被追蹤了克隆指定分支下的內(nèi)容:
clone -b brandName url
參看所有分支:
git branch -a 會(huì)列出當(dāng)前庫(kù)所有的分支(本地亭病、遠(yuǎn)程)
切換分支:
git checkout branchName
加上 -b 參數(shù)會(huì)新建并切換到該分支git checkout -b branchName
創(chuàng)建分支:
git brahch branchName
刪除分支:
git branch --delete branchName
刪除遠(yuǎn)程分支:
git push --delete origin branchName
刪除那些遠(yuǎn)程倉(cāng)庫(kù)不存在的分支:
git remote prune origin
查看本地分支與遠(yuǎn)程分支的對(duì)應(yīng)關(guān)系:
git remote show origin
重命名git本地分支:
git branch -m old_local_branch_name new_local_branch_name重命名git遠(yuǎn)程分支:是先刪除遠(yuǎn)程的分支,然后更改本地分支名嘶居,然后將更改后的分支推送到遠(yuǎn)程
通過這個(gè)命令可以看出 本地分支與遠(yuǎn)程分支的對(duì)應(yīng)關(guān)系罪帖,是否與遠(yuǎn)程有對(duì)應(yīng)關(guān)系。
Local branches configured for 'git pull'
:表示本地分支 從哪個(gè)遠(yuǎn)程分支拉取
Local branches configured for 'git pull'
:表示本地分支 推送到哪個(gè)遠(yuǎn)程分支上去
git 常用命令理解
git fetch
將某個(gè)遠(yuǎn)程主機(jī)的更新 git fetch <遠(yuǎn)程主機(jī)名>
若要更新所有分支邮屁,命令可以簡(jiǎn)寫為: git fetch
上面命令將某個(gè)遠(yuǎn)程主機(jī)的更新整袁,全部取回本地。默認(rèn)情況下佑吝,git fetch取回所有分支的更新坐昙。如果只想取回特定分支的更新,可以指定分支名,如下所示: git fetch <遠(yuǎn)程主機(jī)名> <分支名>
比如芋忿,取回origin主機(jī)的master分支: git fetch origin master
所取回的更新炸客,在本地主機(jī)上要用遠(yuǎn)程主機(jī)名/分支名的形式讀取。比如origin主機(jī)的master分支戈钢,就可以用origin/master
讀取痹仙。
git branch命令的-r選項(xiàng),可以用來查看遠(yuǎn)程分支殉了,-a選項(xiàng)查看所有分支开仰。
$ git branch -r
origin/master
$ git branch -a
* master
remotes/origin/master
上面命令表示,本地主機(jī)的當(dāng)前分支是master宣渗,遠(yuǎn)程分支是origin/master
抖所。取回遠(yuǎn)程主機(jī)的更新以后梨州,可以在它的基礎(chǔ)上痕囱,使用git checkout
命令創(chuàng)建一個(gè)新的分支。
git cherry-pick
場(chǎng)景: 如果你的程序已經(jīng)發(fā)布了一個(gè)版本0.1.1, 代碼分支叫release-0.1.1, 現(xiàn)在正在開發(fā)0.1.x, 我們?cè)陂_發(fā)分支進(jìn)行后續(xù)的開發(fā)暴匠,那么有一天產(chǎn)品說, 要把正在開發(fā)的某個(gè)特性(功能)提前上線, 也就是說要把開發(fā)分支上的某些更改移到release-0.1.1的版本上, 那么怎么辦呢?鞍恢。
思考: 我們的目標(biāo)是:需要把這個(gè)需要發(fā)的功能相關(guān)的代碼移植到想relesase-0.1.1分支上面,這里有一種比較非體力的方法,就是把要發(fā)布的內(nèi)容挑出來帮掉,然后移到新的分支(基于relesase-0.1.1拉出來的分支)上去弦悉,然后把新的分支合并到relesase-0.1.1。(不能把開發(fā)分支直接合并到relesase-0.1.1)
推薦解決方式: 使用git cherry-pick cherry-pick會(huì)重演某些commit, 即把某些commit的更改重新執(zhí)行一遍蟆炊』颍或者簡(jiǎn)單理解這里有10次commit提交的內(nèi)容,你可以任意挑選出其中5次commit的內(nèi)容涩搓,然后重新執(zhí)行這5次提交(這就是重演)污秆。
- 基于release-2.0分支新建分支release-2.1, 并且到新創(chuàng)建的分支上
git checkout -b release-2.1 release-2.0
- 將dev-3.0分支上的某些commit在release-2.1分支上重演
git cherry-pick dev-3.0分支的某些commit-hash
如:
git cherry-pick
20c2f506d789bb9f041050dc2c1e954fa3fb6910
2633961a16b0dda7b767b9264662223a2874dfa9
5d5929eafd1b03fd4e7b6aa15a6c571fbcb3ceb4
多個(gè)commit-hash使用空格分割, commit-hash最好按提交時(shí)間先后排列, 即最先提交的commit放在前面.
cherry-pick不僅可以用在不同分支之間, 還可以用在同一個(gè)分支上.
不同分支的用法如上所述. 同一分支用法也是一樣的, 同一分支使用情形:
比如說你在某一個(gè)向某個(gè)分支中添加了一個(gè)功能, 后來處于某種原因把它給刪除了,
然而后來某一天你又要添加上這個(gè)功能了, 這時(shí)候就可以使用cherry-pick把添加那個(gè)功能的commit, 再重演一遍.
常見分支操作 -新建分支
情況1 :
如果遠(yuǎn)程新建了一個(gè)分支,本地沒有該分支昧甘,可以用 git checkout --track origin/branch_name
這時(shí)候本地會(huì)新建一個(gè)分支名叫branch_name
良拼,會(huì)自動(dòng)跟蹤(track)遠(yuǎn)程的同名分支branch_name(就可以在這個(gè)本地分支上推拉代碼)
用上面中方法,得到的分支名永遠(yuǎn)和遠(yuǎn)程的分支名一樣充边,如果想新建一個(gè)本地分支不同名字庸推,同時(shí)跟蹤一個(gè)遠(yuǎn)程分支可以利用。
git checkout -b new_branch_name branch_name
這條指令本來是根據(jù)一個(gè)branch_name
分支分出一個(gè)本地分支new_branch_name
浇冰,但是如果所根據(jù)的分支branch_name
是一個(gè)遠(yuǎn)程分支名贬媒,那么本地的分支會(huì)自動(dòng)的track
遠(yuǎn)程分支。
注意:一般用
git push --set-upstream origin branch_name
來在遠(yuǎn)程創(chuàng)建一個(gè)與本地branch_name
同名的分支并跟蹤湖饱;利用git checkout --track origin/branch_name
來在本地創(chuàng)建一個(gè)與branch_name
同名分支跟蹤遠(yuǎn)程分支.
當(dāng)使用git checkout -b new_branch_name origin/branch_name
當(dāng)提交的時(shí)候會(huì)報(bào)這個(gè)錯(cuò):
fatal: The upstream branch of your current branch does not match
the name of your current branch. To push to the upstream branch
on the remote, use
git push origin HEAD:master
To push to the branch of the same name on the remote, use
git push origin dev-test
這是由于Git
中push.default
的設(shè)置的原因
Git
中push.default
可以指定在沒有明確指定遠(yuǎn)程分支的情況下掖蛤,默認(rèn)push的遠(yuǎn)程分支,其取值可以是:
nothing
-push
操作無(wú)效井厌,除非顯式指定遠(yuǎn)程分支(意思就是 push的時(shí)候 必須指定遠(yuǎn)程的分支)current
-push
當(dāng)前分支到遠(yuǎn)程同名分支蚓庭,如果遠(yuǎn)程同名分支不存在則自動(dòng)創(chuàng)建同名分支(central 和 non-central workflows
都適用)upstream
-push
當(dāng)前分支到它的upstream
分支上(通常用于central workflow
)simple
-simple
和upstream
是相似的(通常用于central workflow
),只有一點(diǎn)不同仅仆,simple
必須保證本地分支和它的遠(yuǎn)程upstream
分支同名器赞,否則會(huì)拒絕push
操作matching
-push
所有本地和遠(yuǎn)程兩端都存在的同名分支-
central / non-central workflows
是Git
的兩種常見工作流場(chǎng)景:-
central workflows
- 集中式工作流,一個(gè)分支的push
和pull
都是同一個(gè)遠(yuǎn)程倉(cāng)庫(kù) -
non-central workflows
- 非集中式工作流墓拜,一個(gè)分支的push
和pull
可能分別都有不同的遠(yuǎn)程倉(cāng)庫(kù)
-
在Git 2.0之前港柜,push.default的內(nèi)建值被設(shè)為'matching',2.0之后則被更改為了'simple'咳榜。
通過git remote show origin
可以看到每個(gè)分支的具體信息: (例如 git checkout -b local origin/daily/dev
)
Local branches configured for 'git pull':
local merges with remote /daily/dev
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
由于git checkout -b local origin/daily/dev
會(huì)自動(dòng)創(chuàng)建遠(yuǎn)程分支/daily/dev
和本地分支local的跟蹤關(guān)系夏醉。
其中Local branches configured for 'git pull'
:下的就是upstream
跟蹤分支。
可以看出涌韩,遠(yuǎn)程分支/daily/dev
和本地分支local
建立了git pull
的關(guān)系畔柔,但是沒有建立git push
的關(guān)系。此時(shí)如果強(qiáng)行push臣樱,不會(huì)成功靶擦,會(huì)出現(xiàn)如下提示:
fatal: The current branch new has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin develop
這種提示的處理方式下面會(huì)給出具體的處理方法腮考。
情況2 :
本地新建分支,然后推送到遠(yuǎn)程玄捕,可以使用git branch branch_name
或者git checkout -b branch_name
(新建并切換到該分支) 新建一個(gè)本地分支,然后修改了代碼 執(zhí)行add 踩蔚、commit、最后執(zhí)行push操作 發(fā)現(xiàn)會(huì)發(fā)現(xiàn)報(bào)錯(cuò):
# git push
fatal: The current branch make-scripts-executable has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin branch_name
這是因?yàn)镚it不知道你要提交到哪個(gè)分支上去, 所以需要你指定提交的分支, 直接從本地檢出的新分支枚粘,第一次push馅闽,遠(yuǎn)程倉(cāng)庫(kù)還沒有與之建立tracing關(guān)系的分支,所以需要設(shè)置upstream馍迄,這個(gè)設(shè)置一次之后捞蛋,后面再push的時(shí)候就不用設(shè)置了。
如果不想這樣寫則需要指定提交到遠(yuǎn)程的分支: git push origin branch_name
柬姚。
git push origin branch_name
推向制定的分支拟杉,最強(qiáng)暴的方法。但是每次提交都要指定量承,太麻煩了(而且還容易出錯(cuò))搬设。所以需要與遠(yuǎn)程分支關(guān)聯(lián)。
所以使用git push --set-upstream origin branch_name
遠(yuǎn)程分支關(guān)聯(lián)撕捍。 這樣就不用每次push的時(shí)候都指定分支了拿穴,都會(huì)提交到關(guān)聯(lián)的遠(yuǎn)程分支上去。(branch_name是遠(yuǎn)程分支名)
常見分支操作 合并分支
git merge
命令用于將兩個(gè)或兩個(gè)以上的開發(fā)歷史加入(合并)一起忧风。 將 merge 后面的分支合并到當(dāng)前分支默色。
- 將分支dev合并到當(dāng)前分支中,自動(dòng)進(jìn)行新的提交:
git merge dev
- 合并分支 branch1 和 branch2 在當(dāng)前分支的頂部狮腿,使它們合并:
git merge branch1 branch2
- 合并branch1分支到當(dāng)前分支腿宰,使用ours合并策略:
git merge -s ours branch1
- 將分支branch1合并到當(dāng)前分支中,但不要自動(dòng)進(jìn)行新的提交:
git merge --no-commit branch1
Git checkout [文件名]缘厢、git reset HEAD [文件名] 吃度、git reset [哈希值] 的應(yīng)用場(chǎng)景。
git reset HEAD [文件名]
通過git reset [文件名] 可以將暫存區(qū)的文件放出來 贴硫, 但是我們的工作區(qū)的內(nèi)容沒有改變椿每。只是相當(dāng)于 對(duì)[文件名] 不執(zhí)行 git add 操作 。 類似于后退操作英遭。
git checkout [文件名]
工作區(qū)回退:如果比對(duì)后间护,發(fā)現(xiàn)這次改動(dòng)不是我們想要的,那么我們可以回退到未修改之前挖诸,(在vsCode等編輯器里面汁尺,可以放棄修改)
git checkout readme.txt
git checkout .
git checkout -- readme.txt // 以防判斷成分支
下面這串?dāng)?shù)字是我們新加的, 通過git status 我們可以看到readme.md文件做了修改
使用 git checkout [文件名] 可以將它變成修改前的是 ,意思就是放棄本次修改税灌。 執(zhí)行改命令后均函,發(fā)現(xiàn)添加的數(shù)字不見了
git status 顯示文件沒有修改。
如果我們已經(jīng)添加到了暫存區(qū)(意思已經(jīng)執(zhí)行 git add
操作了)菱涤,如果要退回到修改前苞也,我們應(yīng)該怎么處理呢。
直接通過git checkout [文件名]
是不能將它回退到未修改的樣子的粘秆∪绯伲可以先采用git reset HEAD [文件名]
將它移除暫存區(qū)(意思就是回退在沒有執(zhí)行git add
的時(shí)候), 然后通過git checkout [文件名]
將改文件退回到修改前。
git reset [哈希值]
上面的操作都是在暫存區(qū) 攻走,還沒有使用git commit 提交到本地廠庫(kù) 殷勘。如果已經(jīng)提交到本地廠庫(kù)了又要如何操作呢。
將readme.md文件添加一段文字, 然后提交到本地的廠庫(kù)昔搂。
通過git reflog
可以看到一共有兩個(gè)版本 當(dāng)前的版本是HEAD -> master
然后 在修改文件readme.md
玲销,然后在提交到本地廠庫(kù)。
但是這個(gè)時(shí)候的需求是 回到?jīng)]有添加第二次提交文字的時(shí)候摘符,意思就是要回到上一個(gè)版本贤斜。
可以通過使用 git reset
的命令來完成」淇悖基本的流程是執(zhí)行:git reset --mixed HEAD^
意思就是回退到上一個(gè)版本瘩绒。
可以發(fā)現(xiàn)命令成功了,是不是頁(yè)面也變成了原來的樣子呢带族,然后并沒有改變锁荔。那這個(gè)命令具體做了什么呢?
我們通過看readme.md
和git status
看可以看到
是將它回退沒有執(zhí)行git add
命令之前了,相當(dāng)于你修改了代碼 但是沒有提交的那個(gè)狀態(tài)蝙砌。然后可以通過git checkout readme.md
命令將它變回未修改的狀態(tài)阳堕。
但是如果我們要從現(xiàn)在沒有添加那個(gè)文字的這個(gè)版本 變到添加了文字的版本 要如何操作呢。
通過git reflog
可以看出當(dāng)前的版本是fd8258e
我們使用 git reset --hard HEAD^
, 發(fā)現(xiàn)這里readme.md文件直接被修改了择克。
同時(shí)版本并滅有從fd8258e
變到 a5da32e
而是變到了df0abb9
嘱丢,這里的原因是git的提交是一條時(shí)間線,在這條時(shí)間線上祠饺,fd82582
的上一次提交就是df0abb9
如果要變成指定的版本應(yīng)該采用命令: git reset [哈希值]越驻; --mixed 為默認(rèn)參數(shù)
。
顯示readme.md被修改了道偷,通過左右兩邊的比較可以發(fā)現(xiàn)缀旁。 左邊相當(dāng)于原文件,而右邊相當(dāng)于對(duì)原文件的修改勺鸦〔⑽。可以通過 git checkout readme.md
放棄本次修改。
執(zhí)行git checkout readme.md
頁(yè)面變成了修改之前的换途,同時(shí)也可以使用git statsu
看出沒有做出修改懊渡。