分支的三個版本:
- 遠程版本庫,如 github.com铛嘱;
-
遠程快照霎俩,使用
git branch -r
查看到的 origin/branch-name,相關(guān)信息在.git/refs/remotes
中仁堪; -
本地分支哮洽,使用
git branch
查看到的分支,相關(guān)信息在.git/refs/heads
中枝笨。一般本地分支會關(guān)聯(lián)到對應(yīng)的遠程分支袁铐;
倉庫與版本庫:
可理解為:倉庫 = 版本庫 + 工作區(qū)。版本庫即 .git 文件夾內(nèi)容横浑,版本庫以外的都是工作區(qū)內(nèi)容剔桨。
工作區(qū)、暫存區(qū)徙融、版本區(qū):
- 工作區(qū):即我們能看到的目錄和文件(除了 .git 這個隱藏目錄)洒缀,對代碼的修改發(fā)生在工作區(qū);
- 暫存區(qū):使用
git add .
將工作區(qū)的修改轉(zhuǎn)移到暫存區(qū)欺冀。暫存區(qū)是工作區(qū)和版本庫(分支)的中轉(zhuǎn)站树绩; - 版本庫:使用
git commit -m
將暫存區(qū)的內(nèi)容轉(zhuǎn)移到版本庫中,并生成提交記錄隐轩;
.git 目錄概覽:
- 幾個
HEAD
:-
FETCH_HEAD:
git fetch
用到的饺饭,記錄了遠程倉庫每個分支的 HEAD 指向; - HEAD:本地倉庫所在的版本职车;
- ORIG_HEAD:針對一些危險操作(如 git reset --hard)瘫俊,git 記錄了上次 HEAD 的值以防回退(如可以執(zhí)行 git reset --hard ORIG_HEAD 回退剛剛執(zhí)行的 reset 操作);
-
FETCH_HEAD:
- config:配置信息悴灵;
- hooks/:鉤子 shell 腳本扛芽;
- logs/:操作日志;
- objects/:git 對象积瞒;
- refs:引用川尖;
本地倉庫與遠程倉庫:
- git 是分布式版本管理系統(tǒng)溉跃,大體上分為本地倉庫 和 遠程倉庫汪疮。一個本地倉庫可以關(guān)聯(lián) 0 個或多個遠程倉庫。最常用的遠程倉庫默認命名為 origin巨柒。
- 創(chuàng)建倉庫的幾種方式:
- 基于遠程倉庫創(chuàng)建本地倉庫(clone):
git clone git@github.com:linvanda/cache2go.git
缰贝; - 在本地創(chuàng)建一個空的倉庫:
mkdir proj & cd proj & git init
嘲更;(git init 與 git init --bare 的區(qū)別:git init --bare 生成的是裸版本庫,不帶工作區(qū)揩瞪,相當于 git init 生成的 .git 內(nèi)容);
- 基于遠程倉庫創(chuàng)建本地倉庫(clone):
- 本地倉庫與遠程倉庫的關(guān)聯(lián):
- 創(chuàng)建本地倉庫:
mkdir proj & cd proj & git init
篓冲; - 添加遠程倉庫關(guān)聯(lián):
git remote add origin git@github.com:linvanda/cache2go.git
李破; - 可以添加多個遠程倉庫關(guān)聯(lián)宠哄,再加一個:
git remote add other git@github.com:linvanda/cache2go-other.git
,操作時可指定倉庫嗤攻,如git push other
將推送到 other 倉庫毛嫉;
- 創(chuàng)建本地倉庫:
- 遠程倉庫源的一些操作:
- 查看遠程源列表:
git remote -v
; - 添加遠程源:
git remote add origin git@github.com:linvanda/cache2go.git
妇菱; - 移除遠程源:
git remote remove origin
承粤; - 重命名遠程源:
git remote rename origin new-origin
;
- 查看遠程源列表:
基于遠程倉庫的分支創(chuàng)建本地分支:
-
git fetch
:將 遠程倉庫分支 fetch 到本地的遠程倉庫快照中闯团; -
git checkout branch-name
:自動基于origin/branch-name
快照創(chuàng)建本地分支并切換到該分支辛臊;
基于 master 創(chuàng)建本地分支并推送到遠程倉庫:
-
git checkout master
:切換到 master 分支; -
git pull --rebase
:更新 master 分支到最新版本房交; -
git checkout -b branch-name
:基于 master 創(chuàng)建開發(fā)分支彻舰; -
git add . & git commit -m "commit reason"
,提交修改候味; -
git push -u origin branch-name
:將該分支推送到遠程并在兩者之間創(chuàng)建關(guān)聯(lián)(這樣后面就可以直接執(zhí)行git push
推送分支)刃唤;
git pull 的兩種模式:rebase 和 merge
-
merge 模式:直接執(zhí)行
git pull
默認就是該模式。該模式是將遠程分支fetch
下來白群,然后將其merge
到相應(yīng)的本地分支尚胞,并在 log 中生成一條 commit。使用該模式下帜慢,git log
查看 commit 會發(fā)現(xiàn)大量的 merge origin/branch-name into branch-name 的無意義的合并日志笼裳。 -
rebase 模式:
git pull --rebase
。推薦使用的模式崖堤。將遠程分支fetch
下來后侍咱,將其rebase
到本地分支,相當于“追加”密幔,不會生成 commit楔脯。
合并分支:
-
git pull --rebase
,同步當前分支胯甩; -
git checkout test
昧廷,進入 test 分支; -
git pull --rebase
偎箫,同步 test 分支木柬; -
git merge --no-ff feature-order
,將 feature-order 合并到 test 分支淹办; -
git push
眉枕,推到遠程;
分支合并的問題:
- 為啥加
--no-ff
:no ff 是 no fast forward 的縮寫。git merge 默認是fast forward(快進) 模式速挑,該模式下不會生成單獨的 commit谤牡,這對歷史查看和回滾都不便。加 --no-ff 則強制生成獨立的合并 commit姥宝; - 出現(xiàn)沖突咋辦翅萤?出現(xiàn)沖突時一定要找沖突相關(guān)人一起解決,解決完畢后執(zhí)行
git add . & git commit
即可腊满。如果無法解決沖突套么,則要撤銷此次合并:git merge --abort
;
git diff:
-
git diff A B
B相對于A有什么不同碳蛋。如果不指定B胚泌,則B默認是工作區(qū);如果同時不指定A疮蹦,則A默認是暫存區(qū)诸迟。 -
git diff
相當于 git diff stage workspace 。 工作區(qū)相對于暫存區(qū) 有哪些不同愕乎。 -
git diff HEAD
相當于 git diff HEAD workspace 阵苇。 工作區(qū)相對于HEAD區(qū) 有哪些不同。 -
git diff commitId
相當于 git diff commitId workspace感论。 工作區(qū)相對于commitId那次提交 有哪些不同绅项。 -
git diff commitIdA commitIdB
commitIdB相對于commitIdA有哪些不同 -
git diff master
相當于 git diff master workspace: 當前工作區(qū)相對于master分支的最近提交有哪些不同。 -
git diff master HEAD
當前的HEAD相對于master分支最近提交有哪些不同 -
git show commitID
本次提交相對于上次提交有何不同
撤銷修改:
- 撤銷 workspace 中某個文件的修改:
git checkout < filename >
比肄。
變體:git checkout
:撤銷工作區(qū)所有文件的修改快耿。 - 撤銷 stage 中某個文件的修改(將其放入 workspace):
git reset HEAD <filename>
變體:git reset HEAD
撤銷暫存區(qū)所有文件修改到工作區(qū) -
git reset --hard HEAD
撤銷修改并丟棄(不放回工作區(qū)), 此時工作區(qū)內(nèi)容和HEAD中的相同芳绩。
合并 commit:
合并本地多次 commit 為一條 commit:
1. git rebase -i HEAD~4
2. 彈出文本掀亥,將第二行開始的pick改為s(或squash)
3. 保存,退出
4. 推到遠程:git push -f
對比文件修改歷史:
查看某個文件最新代碼中每行是由誰修改的(以及在哪次提交中修改的):
git blame filename
歷史日志 log:
-
git log --grep="test"
搜索提交信息中包含 test 的 -
git log -S abc
搜索修改內(nèi)容包含"abc"的 commit -
git log --date=relative
以相對日期格式顯示日志(如2 hours ago) -
git log —oneline
一行緊湊顯示提交id和注釋 -
git log --abbrev-commit
顯示短 commit id -
git log -5
顯示最近5條提交 -
git log —all
顯示所有分支的提交歷史(默認只顯示當前分支的) -
git log —graph
圖形顯示分支 -
git log --pretty=format:'…'
格式化顯示
格式化顯示日志:
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
可設(shè)置別名:
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative”
刪除 untracked files
git clean -f
連 untracked 的目錄也一起刪掉
git clean -fd
cherry-pick
在分支 A 做了些修改并提交后妥色,想把這些修改應(yīng)用到分支 B搪花,但又不能直接 merge A 到 B,又不想手動 copy嘹害,此時可以用 cherry-pick:
git checkout B
git cherry-pick commitid-from-A
撤銷合并:
- 查看合并提交詳情:git show mergecommitid撮竿,會有如下一行:Merge: 022ff6f b2cd947,其中022ff6f和 b2cd947分別是兩個分支合并前最近提交的commitId笔呀。
- 撤銷合并時用-m指定需要以誰為準(主干mainline):
git revert -m 1 mergecommitid
幢踏,這樣就回退到 022ff6f身上(丟棄掉被合并分支的一系列提交)。 - 撤銷合并前用
git log —graph
能很清晰的看出分支合并關(guān)系以及將要撤銷掉的提交系列许师。 - 一般情況下房蝉,我們都是錯誤合并后需要撤銷到合并之前的狀態(tài)僚匆,因而一般都是
git revert -m 1 …
刪除本地分支:
git branch -D branch-name
刪除遠程分支:
git push origin :branch_name
或
git push --delete origin branch_name
基于遠程分支創(chuàng)建本地分支:
git checkout -b localbranch origin/remotebranch
會創(chuàng)建本地分支localbranch并追蹤到遠程分支。
基于本地分支創(chuàng)建(如基于本地 master)則不會追蹤任何遠程分支搭幻,此時要用 git push -u origin localbranch:remotebranch
推送并追蹤白热。
提交:
git commit -am '…'
-a:add 將未暫存的文件也提交。
代碼評審:
gerrit
或者gitlab的merge request
git flow:
介紹:http://nvie.com/posts/a-successful-git-branching-model/
安裝: apt-get install git-flow
批量刪除分支:
- 批量刪除本地分支:git branch |grep release|xargs git branch -D (刪除本地release分支)
- 批量刪除遠程分支:git branch -r|awk -F '[/]' '/release/ {printf "%s\n", $2}'|xargs -I {} git push --delete origin {} (刪除遠程release分支)
從倉庫中刪除已跟蹤的文件(將文件變成untracked粗卜,不跟蹤):
-
git rm --cached
文件名 -
git rm --cached -r
目錄
刪除遠程不存在的“本地遠程分支“:
很多時候其他人刪除了遠程分支,但我們自己電腦上還有一大堆 origin/... 這些“本地遠程分支”纳击,可執(zhí)行以下指令同步刪除:
git remote prune origin
或者git pull -p
同時推送到多個源:
git remote set-url --add --push origin https://github.com/linvanda/wecarswoole.git
這樣 git push 的時候就會 push 到多個源续扔。
換行符問題(mac、windows焕数、linux混合開發(fā)時可能遇到)
-
git config --global core.autocrlf true
(提交時自動將CRLF轉(zhuǎn)成LF纱昧,檢出時將LF轉(zhuǎn)成CRLF) -
git config --global core.autocrlf input
(提交時自動將CRLF轉(zhuǎn)成LF,檢出時不處理(意味著檢出時是LF))
(以上兩個都是保證git倉庫中是LF) -
git config --global core.autocrlf false
(關(guān)閉堡赔,不處理识脆,是啥就是啥)
其它實踐問題:
- 永遠不要將 test 合并到開發(fā)分支;
- 要經(jīng)常將 master 合并到自己到開發(fā)分支善已;