一.git 簡介
區(qū)塊解釋
- 工作區(qū):就是你現(xiàn)在寫代碼的地方,
- 暫存區(qū):在工作區(qū)修改的記錄保存的地方
- 本地版本庫: 暫存區(qū)通過
commit
命令,將暫存區(qū)的東西生成commit,可以推送到遠端- 遠端版本庫: 服務(wù)器上和本地版本庫一模一樣的倉庫
注:
工作區(qū)和暫存區(qū)通信,暫存區(qū)和本地版本庫通信,本地版本庫和遠端版本庫通信
工作區(qū)不能和遠端直接進行通信,暫存區(qū)也不能和遠端直接進行通信
fast forward
顧名思義:就是最快的前進方式
解釋:git 默認的merge方式.將dev分支合并到master分支時,master分支的指針直接指向dev的commit
優(yōu)點:快
缺點:當(dāng)刪除dev分支后,會丟掉分支信息
解決辦法:(不常用)使用git merge --no-ff dev
,這樣的話master會生成一個新的commit,不會直接使用dev的commit
HEAD(
對應(yīng)的文件存儲在./git/HEAD ref: refs/heads/master
)
- 有一個分支master,master的指針指向該分支的最新commit,HEAD指向master,也就是說HEAD是指向指針的指針
當(dāng)然:HEAD指針不僅可以指向分支,也可以指向tag和commit.
內(nèi)部實現(xiàn):
- tag的內(nèi)部是commit,可用
git cat-file
查看- 分支的內(nèi)部其實也是commit
所以,HEAD其實指向的都是commit
branch(
對應(yīng)的文件存儲在./git/branchs
)
- branch其實是由commit組成的一條鏈表,每個鏈表都有自己的tree和parent commit,都可以通過父節(jié)點找到上一個commit
- 新建dev分支,就是新建一個dev指針指向最新commit,然后HEAD再指向dev
- 切換分支其實就是把HEAD從master更新到dev
git 后悔藥
git restore <文件>...
解釋:該文件還沒有加入到暫存區(qū),使用該命令可以丟掉你在工作區(qū)的改動git checkout --file
--作用對象為工作區(qū)
解釋:該文件已經(jīng)加入到暫存區(qū),現(xiàn)在你在工作區(qū)對該文件進行修改,但還沒有執(zhí)行git add
操作,這時可以使用該命令將暫存區(qū)的內(nèi)容替換工作區(qū)的內(nèi)容,也就是說刪掉基于該暫存的內(nèi)容改動(沒有執(zhí)行git add
操作是重點)git reset HEAD --file
--作用對象為暫存區(qū)
解釋:當(dāng)你執(zhí)行完git add
后,可以使用該命令丟棄掉基于上個暫存的的暫存內(nèi)容,并將丟掉的這部分暫存恢復(fù)到工作區(qū)演示:stage為暫存區(qū),現(xiàn)在workspace工作區(qū)test.md +加了 love字段
第一種情況:執(zhí)行git checkout --file
,那么會將stage的內(nèi)容替換到workspace中,也就是刪除掉了love字段
第二種情況:執(zhí)行git add test.md
將love加入暫存區(qū),那么可以使用git reset HEAD --file
丟掉love這個暫存,并將丟掉的暫存恢復(fù)到工作區(qū),也就是說工作區(qū)回到了添加love這個字段的狀態(tài)
二.git config設(shè)置
-
git config --global user.name 'lyk'
設(shè)置姓名 -
git config --global user.email 'lyk@163.com'
設(shè)置郵箱 -
git config --global --list
查看已經(jīng)設(shè)置的內(nèi)容
注:
其中--global
可以替換為--local
--system
, 他們用法一樣,作用域不一樣.
--local
只針對某個git倉庫
--global
針對當(dāng)前用戶的所有倉庫
--system
針對系統(tǒng)所有的登錄用戶有效
如果多次設(shè)置產(chǎn)生沖突,那么有效順序為--local
>--global
>--system
可以在.git/config文件下找到我們通過命令行命令設(shè)置的姓名锐借、郵箱等
三.git 常用命令
-
git help --web log
查看幫助
本地
git init
創(chuàng)建倉庫(包含.git),使用 ls -ah可以查看隱藏文件git add 需要添加的文件
添加文件到git的暫存區(qū)git commit -m "修改的內(nèi)容"
提交到git暫存區(qū),需要填寫你修改了哪些東西git commit -am "修改的內(nèi)容"
== add.+commit的集合(簡寫而已)git commit --amend
修改最近一次commit提交的內(nèi)容git rebase -i commit的id
修改某次commit提交的內(nèi)容(可以合并多個commit)git status
查看git的狀態(tài)git blame 文件
查看文件的修改記錄git mv 舊文件名 新文件名
git mv 命令用于移動或重命名一個文件、目錄叔壤、軟連接瞎饲。git diff
工作區(qū)和暫存區(qū)的不同git diff 被修改的文件
查看文件被修改的地方git diff commit1
工作區(qū)和commit(版本庫)的不同,commit可以換成HEADgit diff commit1 commit2 --文件
對比兩個commit的不同之處(可以針對某幾個文件)git diff branch1 branch2
對比兩個分支的不同之處(其實分支也是commit)git diff HEAD HEAD^
或者git diff HEAD HEAD~1
對比當(dāng)前commit和其父commit之間不同git diff --cached
對比暫存區(qū)和HEAD(即上一個commit)的不同,默認HEAD,可換成commitIDgit log
查看當(dāng)前分支提交的日志git log --oneline
快速查看當(dāng)前分支日志git log refs/remotes/origin/master
查看遠程分支日志git log -3
查看3跳日志git log -a
或者git log --all
查看所有分支的提交日志git log --graph
圖形化結(jié)構(gòu)查看當(dāng)前分支日志git log --oneline --graph
組合命令,快速并且圖形化結(jié)構(gòu)查看當(dāng)前分支日志git reset HEAD
清除暫存區(qū)的內(nèi)容,恢復(fù)到和HEAD的內(nèi)容一樣git reset HEAD -- 文件
清除暫存區(qū)某個文件的內(nèi)容,恢復(fù)到和HEAD的內(nèi)容一樣git reset --hard HEAD^
分支退回到上個版本(git reset --hard HEAD~100,退回到100個版本)git reset --hard 版本id
分支退回到指定的版本git reflog
記錄你每一次操作HEAD的命令日志git revert??????
git checkout ."
或者"git checkout -- <file>
用git暫存區(qū)全部或指定的文件替換工作區(qū)的文件口叙。這個操作很危險炼绘,會清除工作區(qū)中未添加到暫存區(qū)的改動。 (就是丟棄工作區(qū)的相對于暫存區(qū)的修改,也就是基于該暫存區(qū)的修改)git rm 文件
將文件從工作區(qū)已跟蹤文件清單中移除,相當(dāng)于rm + git add
如果想撤銷的話, -------------
1step(先使用git reset HEAD 文件
刪除rm操作這個新的暫存內(nèi)容,并將改暫存內(nèi)容恢復(fù)到工作區(qū)),然后
2step(使用git checkout --文件
將暫存區(qū)的內(nèi)容替換到工作區(qū),也就是取消了rm操作)git rm -f <file>
如果刪除之前修改過并且已經(jīng)放到暫存區(qū)域的話妄田,則必須要用強制刪除選項 -fgit rm --cached <file>
直接從git暫存區(qū)刪除文件俺亮,工作區(qū)則不做出改變git cherry-pick 4c805e2
將commit嫁接到當(dāng)前分支git stash
保存工作區(qū)的修改git stash list
查看stash列表git stash pop
恢復(fù)工作區(qū)的修改, 從stash列表中移除最近的stashgit stash apply
恢復(fù)工作區(qū)的修改, 不移除, 依然保留該stashgit stash apply stash@{0}
恢復(fù)指定的stash到工作區(qū)中git stash drop stash@{0}
從stash列表中移除指定stashgit cat-file -t
查看git文件的類型git rerere
可以重放commit之前的操作(rebase時可以使用)git clean -fd
清空工作區(qū)未跟蹤的文件&文件夾
遠程倉庫
-
git remote add origin git@github.com:xx.git
關(guān)聯(lián)遠程倉庫(origin是遠端的名字,不一定叫origin, 以后就可以用origin這個簡寫代替git倉庫地址) -
git push -u origin master
把本地分支提交到遠程master -
git clone git@xx.git
克隆遠程倉庫 -
git remote -v
查看遠程倉庫信息 -
git fetch
從遠程拉取分支 -
git pull
等于git fetch+merge
,從遠程抓取分支并和本地的分支合并 -
git push origin src:dest
git push的非縮寫版本,src代表本地分支,dest目標(biāo)遠程分支 -
git pull origin src:dest
git pull的非縮寫版本,src代表遠程分支,dest代表本地分支(和push相反)
分支
git branch
查看本地分支,分支前面帶*代表當(dāng)前分支git branch -a
查看所有的分支,包括本地和遠程的分支git branch -vv
查看本地分支,并附帶最后一條commit記錄git branch 分支
創(chuàng)建分支git checkout 分支
切換分支git checkout -b 分支
創(chuàng)建并切換分支git checkout --track origin/分支
創(chuàng)建并切換分支,分支名與遠端一樣(上個命令的簡寫,但是不能自定義分支名)git checkout -b 新分支 基于的分支(可以是遠端分支)
基于某個分支上創(chuàng)建新的分支,并切換到新分支git merge 分支
合并某分支到當(dāng)前分支git merge --allow-unrelated-histories 分支
強制合并沒有關(guān)聯(lián)的兩個分支git branch -d 分支
刪除某分支git branch -D 分支
強制刪除某分支git push origin 空格:遠程分支名稱
刪除遠程分支(空格替換遠程分支,相當(dāng)于刪除)git push origin --delete 遠程分支名稱
刪除遠程分支
標(biāo)簽
-
git tag v1.0
默認打在最新的commit -
git tag v2.0 67786678
給某一次commit打標(biāo)簽 -
git tag -a v1.0 -m 注釋
打標(biāo)簽&加上提示 -
git tag
查看標(biāo)簽 -
git tag -d
刪除本地標(biāo)簽 -
git push origin 空格:refs/tags/v1.0
刪除遠程標(biāo)簽 -
git push origin --delete tag v1.0
刪除遠程標(biāo)簽 -
git show v1.0
查看標(biāo)簽信息 -
git push origin v1.0 v2.0
將標(biāo)簽推送到遠端,可以同時推送多個 -
git push origin --tags
將所有標(biāo)簽推送到遠端 -
git push origin refs/tags/v1.0:refs/tags/v1.0
推送tag完整寫法
四.安裝gitk
使用gitk圖形化界面來查看git
brew update
brew install git
brew install git-gui
使用方法:gitk
或者gitk --all
使用gitk -a &
可以開啟多線程,這樣終端和wish都可以使用
六. git 技巧
組合搜索
github組合搜索:搜索自己想要的倉庫時,可以在搜索內(nèi)容例如deepfeak
加上文件名稱,
例如deepfeak in:readme
, --------------------------------------搜索出來的是倉庫
例如:從文件名中搜索想要的字段deepfeak filename:readme.txt
,--搜索出來的是code
例如:篩選星數(shù)deepfeak stars>:100
,
或者直接使用高級搜索
遠端的pull request設(shè)置
可以在github上設(shè)置pull request的選項
如果設(shè)置為merge
,則自動合并分支
如果設(shè)置為aquash and merge
,則自動整個多個commit為一個commit并cheery-pick到合并的分支
如果設(shè)置為rebase and merge
,則將多個commit用cheery-pick到合并的分支(如果多個commit有沖突,設(shè)置為rebase則有可能merge失敗.所以還是squash更安全一點)
- squash和rebase都可以使merge操作變成線性的,但是rebase保留了多個commit,而squash只保留了整合后的一個commit
七.git 問題
-
分離頭指針的問題
解釋:HEAD指針和目前你的工作區(qū)的內(nèi)容不一致就會出現(xiàn)detached HEAD
state(例如在master上使用git checkout -commit
)
解決辦法:使用git branch newBranch 3d4fed
創(chuàng)建一個以3d4fed commit為基準(zhǔn)的新分支newBranch,最后merge到master分支上
- 如果已經(jīng)丟失,可用
git reflog
查看提交記錄,參考:http://www.reibang.com/p/91a0f8feb45d
- git對比svn?
git本地存在版本庫,而svn是集中式的管理系統(tǒng),只有服務(wù)器有版本庫. - gitlab和github都支持CI/CD(持續(xù)繼承,持續(xù)交付)功能,類似jinkens.
- git submodule的用處
我覺得可以搞搞組件化,以后可以試試 0.0