GIT速查手冊
一、GIT
1.1 簡單配置
git是版本控制系統,與svn不同的是git是分布式,svn是集中式
配置文件位置
# 配置文件
.git/config 當前倉庫的配置文件
~/.gitconfig 全局配置文件
# 查看所有配置項
git config --list
友好的查看日誌
# 設置別名 # 友好的查看日誌 git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --all" git log --decorate --oneline --graph --all git lg
設置用戶名和郵箱
# 設置用戶名和郵箱
git config --global user.name "xxx"
git config --blobal user.email "[email protected]"
1.2 工作區和暫存區
工作區(Working Directory)是當前文件夾,當前文件夾下的.git文件夾是版本庫(Repository)。版本庫裏有很多東西,其中有
- 最重要的就是暫存區(stage或index)
- Git為我們自動創建的第一個分支master
- 指向master的一個指針叫HEAD
工作區--暫存區(stage/index)--當前分支(master)--遠程庫
關系圖
版本說明
HEAD 當前版本
HEAD^ 上一版本
HEAD^^ 上上版本
HEAD~100 往上100個版本
1.3 add/commit/diff/reset
add命令
commit命令
diff命令
reset
二、常用命令
2.1 init/add/commit/status/log
init
cd learngit
git init
# 在某目錄下執行命令後,該目錄會生成一個.git的隱藏文件夾,這個目錄就是一個版本庫了
# 所有版本控制系統只能跟蹤文本文件的發動
# 如TXT文件中刪除了第4行,圖片等二進制文件作為一個整體
# 統一用UTF-8編碼
add
# 添加一個文件到暫存區(Stage) vi readme.txt git add readme.txt
commit
# 將文件提交給HEAD
git commit -m 'wrote a readme file'
# 不產生新快照的提交
git commit --amend
查看狀態
git status
# 通過該命令可以清楚的了解當前版本庫中的文件處於什麽狀態
查看歷史
git log
git log --pretty=oneline
git lg
# 自定義的一個別名,參照 簡單設置
git reflog
# 查看執行的每一條命令
2.2 文件對比
準備
# 工作區的readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
# 暫存區的readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files by stage.
# master的readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.
比較工作區與暫存區中的文件
git diff -- readme.txt
比較工作區與版本庫中的文件
git diff HEAD -- readme.txt
比較暫存區與版本庫
git diff --cached HEAD
比較兩個歷史快照
git diff id1 id2
2.3 版本回退
有如下幾個版本:
查看歷史記錄是這樣的:
回退到指定版本:
git reset HEAD^/comment_id
# comment_id,ID號,前7位,可以通過git reflog和git log命令進行查看
版本庫覆蓋xxx
# 工作區----暫存區(stage)----版本庫(HEAD)----服務器
# 三種模式soft/mixed/hard,默認是mixed
# 版本庫裏上一版本覆蓋最新版本
git reset --soft HEAD^
# 1.移動HEAD的指向,將其指向上一個快照
# 版本庫上一版本覆蓋最新版本和暫存區
git reset --mixed HEAD^
# 1.移動HEAD的指向,將其指向上一個快照
# 2.將HEAD移動後指向的快照回滾到暫存區域
# 版本庫上一版本覆蓋最新版本和暫存區和工作區
git reset --hard HEAD^
# 1.移動HEAD的指向,將其指向上一個快照
# 2.將HEAD移動後指向的快照回滾到暫存區域
# 3.將暫存區域的文件還原到工作目錄
暫存區覆蓋工作區
# 暫存區的內容覆蓋工作區(丟棄工作區的修改)
# 撤銷工作區的修改
# 沒有--,該命令就是切換分支的命令了
git checkout -- readme.txt
版本庫覆蓋暫存區
# 版本庫的內容覆蓋暫存區(丟棄暫存區的修改)
# 撤銷暫存區的修改
git reset HEAD readme.txt
2.4 暫存區修改
這樣一種場景:工作區,暫存區,版本庫裏內容一樣,類似.project類似這種eclipse的項目配置文件也存在於版本控制中,現在把.project這類文件加入到忽略名單後
# 這個命令是把.project從暫存區中刪除
git rm --cached .project
# 提交暫存區
git commit -m "delete .project"
2.5 刪除/重命名
# 只能刪除工作區和暫存區中的文件
git rm filename
# git rm readme.txt與如下兩個命令等價
rm readme.txt
git add readme.txt
# 如果工作區和暫存區中的文件內容不同時,下面兩個命令可把兩個都刪除
git rm -f filename
git rm --cached filename
# 重命名
git mv filename1 filename2
三、遠程倉庫
3.1 免登錄設置
Windows下生成ssh-keygen
1.安裝Git
2.打開Git Bash
3.輸入 ssh-keygen -t rsa -C "your email"
Linux下生成ssh-key
ssh-keygen -t rsa -C "your email"
cat ~/.ssh/id_rsa.pub
# ~/.ssh/id_rsa 這是私鑰
# ~/.ssh/id_rea.pub 這是公鑰
# 驗證
ssh -T [email protected]
3.2 遠程庫命令
關聯遠程倉庫
# 把本地倉庫與遠程倉庫相關聯
git remote add origin [email protected]:yysue/learngit.git
# yysue:github賬戶名或gitee賬戶名
# origin:遠程庫的名字,這是Git默認的叫法
# 關聯分支
git branch --set-upstream-to=origin/master master
# 將本地的master分支與遠程origin庫的master分支關聯
# pull,第一次pull加--allow-unrelated-histories
# https://stackoverflow.com/questions/37937984/git-refusing-to-merge-unrelated-histories-on-rebase
git pull --allow-unrelated-histories
直接修改配置
# 當前版本庫目錄下
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
[remote "origin"]
url = [email protected]:yysue/mysqldba.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
查看遠程庫
git remote -v
推送到遠程庫
git push -u origin master
# 把本地所有內容推送到遠程庫上
# -u參數,不但會把本地master分支推送到遠程master分支,還會把本地master分支與遠程master分支相關聯
# 第一次推送用-u,以後用就可以不用了
git push origin master
從遠程庫抓取
git pull origin master
從遠程庫克隆
git clone [email protected]:h2o1k/gitskills.git ssh協議,速度快
git clone https://github.com/h2o1k/gitskills.git https協議
四、分支管理
4.1 branch/checkout/merge
查看master分支
master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點
創建並切換到dev分支
# 查看當前分支的命令
git branch
git checkout -b dev
# -b 表示創建並切換,與下面兩條命令等價
git branch dev
git checkout dev
# 再查看一下分支
git branch
在dev分支提交
vi dev.txt
Creating a new branch is quick.
git add dev.txt
git commit -m "add dev.txt"
切換到master分支
git checkout master
dev合並到master
git merge dev -m "merge dev"
# merge合並指定分支到當前分支,
# so,必須在master分支下執行上述命令
保留分支信息的合並
git merge --no-ff -m "merge" dev
# --no-ff會保留分支信息
通常,分支合並時,Git會用Fast forward模式,這種模式下,刪除分支後,會丟失分支信息,禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息
刪除dev分支
git branch -d dev
產生沖突
master分支和feature1都有新的提交
解決沖突
編輯沖突文件,然後再添加、提交、合並,最後刪除分支feature1
查看日誌
分支管理策略
4.2 stash
我們有時會遇到這樣的情況,正在分支a上開發一半,然後分支b上發現Bug,需要馬上處理。
這時候分支a上的修改怎麽辦呢,git add 是不行的,有的git客戶端版本會提示還有add過的文件沒提交不能切換分支,有的git客戶端版本會把修改帶到b分支。
git stash 就是解決這個問題,它把當前工作區的修改和git add的內容都保存到一個地方,然後git reset HEAD,使工作區回到上一次提交,處於幹凈狀態。然後就可以很放心的切到另外的分支b幹活了。
git stash save “先給我保存一下,我要去別的分支修bug”
git stash list
# 切換到其他分支去修改bug
# ...
# 再切換到打stash的分支
git stash pop
# git stash pop相當於執行git stash apply和git stash drop
git stash apply stash@{num}
4.3 rebase
有的時候我們在一個分支a開發的時候,master已經進入了很多修改,這時候如果把a的修改提交上去,可能就會跟主幹有沖突,需要在主幹解決沖突才能提交,這樣比較難看。
這時候git rebase就有用了,git rebase BRANCH_NAME可以把BRANCH_NAME分支的修改帶到當前分支來,這樣當前分支就有了BRANCH_NAME分支的所有內容,這樣在當前分支開發的內容提交以後不會跟BRANCH_NAME有沖突,沖突在當前分支就可以解決。
4.4 小技巧
可以取消已經提交的commit,一般我們只用git reset HEAD^。因為每個分支可能開發過程中為了保存過程以便回溯會有很多commit,但是我們要求進入主幹時,每個功能和bugfix只能有一個提交,因此可以先用git reset退回到最早的commit,然後把自己的修改最後打包成一個commit,再去跟主幹合並。
利用這兩個命令,我們可以很好的管理我們的MySQL開發。我們只有一個master分支作為主幹,不允許在主幹上直接開發。每個同學根據feature和bug的issue建立分支,然後在分支上開發,不管開發過程中有多少個commit,我們要求最終提交每個bugfix或feature只能有一個提交。因此每個同學完成開發後,都需要git reset 退到最早的commit,git stash save寶存一下自己的修改,然後git checkout master; git pull拖一下最新的主幹,然後返回自己的分支,再做git rebase master,把當前分支推進到主幹,最後git stash pop彈出修改,有沖突則在當前分支解決,再git push。
# 此時commit id為a37b9ff,切換到開發版本dev
git checkout -b dev
# 實現了一個功能xxx,期間多次commit
...
# xxx開發完畢後,合並到主分支要求只有一個commit
git reset a37b9ff
git stash save "保存開發功能xxx的修改"
git checkout master
git pull
git checkout dev
git rebase master
git stash pop
# 處理沖突
git add .
git commit -m "功能xxx"
git checkout master
git merge --no-ff -m "merge 功能xxx" dev
4.5 常用分支命令
# 查看當前分支
git branch
# 創建分支dev
git branch dev
# 切換到分支dev
git checkout dev
# 創建並切換到分支dev
git checkout -b dev
# 合並指定分支(dev)到當前分支
git merge dev
# 刪除分支dev, 如果分支有未提交的這樣刪除不了
git branch -d dev
# 強制刪除
git branch -D dev
# 查看分支合並情況
git log --pretty=oneline --graph --abbrev-commit
# master轉gh-pages
# 創建一個沒有父節點的分支gh-pages
git checkout --orphan gh-pages
五、標簽管理
5.1 常用標簽命令
# 切換到要打標簽的分支上
git branch
git checkout master
# 打標簽
git tag v1.0
# 默認標簽是打在最新提交的commit上,也可以指定commit id
# git log --pretty=oneline --abbrev-commit
git tag v0.9 <commit id>
# 查看標簽列表
git tag
# 查看某標簽信息
git show v0.9
# 標簽加註釋
git tag -a v0.1 -m "version 0.1 released" 2428164
# 可以用PGP簽名標簽
git tag -s v0.2 -m "signed version 0.2 released" fac145a
# 刪除標簽
git tag -d v0.1
# 把標簽推送到服務器
git push origin v1.0
# 一次性推送全部尚未推送的本地標簽
git push origin --tags
# 刪除遠程庫標簽
# 先刪除本地標簽
git tag -d v0.9
# 再刪除遠程庫標簽
git push origin :refs/tags/v0.9
六、使用GitHub
6.1 Fork/克隆
七、自定義Git
# 如果一個jar文件已經加到忽略文件裏邊了
# 想把一個jar文件添加到版本庫
git add -f aaa.jar
八、問題
8.1 註釋輸入不了中文了
# Git安裝目錄 D:\Program Files\Git
# 編輯如下文件D:\Program Files\Git\etc\inputrc
# 確保如下行的配置如下,就可以保證輸入中文註釋了
set output-meta on
set convert-meta off
九、參考
- Git教程-廖雪峰
- 一些Git操作的技巧
GIT速查手冊