Git 學習雜記
Git
儲存的不是檔案差異或者變化量,而是一系列檔案快照
三種狀態
已提交(committed): 該檔案已經被安全的儲存在本地資料庫中
已修改(modified):修改了某個檔案,但是沒有提交儲存
已暫存(staged):已修改的檔案放在下次提交時要儲存的清單中
Git配置
# 1. 配置個人資訊 git config --global user.name "iFan" git config --global user.email [email protected] # 2. 配置文字編輯器 git config --global merge.tool vimdiff # 3. 配置差異分析工具 git config --global merge.tool vimdiff # 4. 檢視配置資訊 git config --list
倉庫配置
# 1. 初始化Git倉庫
git init
# 2. 新增檔案
git add .
git add Readme
git add *.c
# 3. 提交
git commit -m 'init project'
新增忽略檔案 .gitignore
檢視倉庫的狀態 git status
檢視檔案差異 git diff
刪除記錄的檔案 git rm file
檔案改名 git mv old_file new_file
檢視日誌
# 檢視日誌 git log # -p 展開顯示每次提交的內容差異 # -2 僅顯示最近兩次更新 git log --p -2 # --stat 僅顯示簡要的增改行數統計 git log --stat # --pretty 可以指定使用完全不同於預設格式的方式展示提交歷史 # online 將每個提交放在一行顯示 # short full fuller git log --pretty=online # 格式化資訊 # 選項 佔位符說明 # %H 提交物件的完整雜湊字串 # %h 提交物件的簡短雜湊字串 # %T 樹物件(tree)的完整雜湊字串 # %t 樹物件的簡短雜湊字串 # %P 父物件(parent)的完整雜湊字串 # %p 父物件的簡短雜湊字串 # %an 作者(author)的名字 # %ae 作者的電子郵件地址 # %ad 作者修訂日期(可以用 -date= 選項定製格式) # %ar 作者修訂日期,按多久以前的方式顯示 # %cn 提交者(committer)的名字 # %ce 提交者的電子郵件地址 # %cd 提交日期 # %cr 提交日期,按多久以前的方式顯示 # %s 提交說明 git log --pretty=format:"%h - %an, %ar : %s" # 使用online或format時結合--graph選項 git log --pretty=format:"%h %s" --graph # 檢視指定時間的提交 # 選項 說明 # -(n) 僅顯示最近的 n 條提交 # --since, --after 僅顯示指定時間之後的提交。 # --until, --before 僅顯示指定時間之前的提交。 # --author 僅顯示指定作者相關的提交。 # --committer 僅顯示指定提交者相關的提交。 git log --pretty="%h:%s" --author=gitster --since="2008-10-01" --before="2008-11-01" --no-merges --t
撤銷操作
# 撤銷最後一次提交
git commit --amend
# 撤銷提交,新增檔案,再次提交
git commit -m 'initial commit'
git add file
git commit --amend
# 取消暫存檔案
git reset HEAD file
遠端倉庫
# 下載 git clone url # 列出遠端倉庫地址 git remote -v # 新增遠端倉庫 git remote add remote-name url # 拉取指定倉庫資訊,不合並 git fetch remote-name # 拉取併合並 git pull # 提交到遠端倉庫 git push [remote-name] [branch-name] # 檢視遠端倉庫的資訊 git remote show origin # 刪除遠端倉庫 git remote rm remote-name
標籤
# 檢視標籤
git tag
git tag -l 'v.1.*'
git show v.1.2
# 新建標籤
git tag -a v.1.2 -m 'version 1.2'
git tag v.1.3
git tag -a v.1.4 提交物件的驗證和
# 傳送到遠端倉庫
git push origin [tagname] # 傳送指定
git push origin --tags # 傳送所有
分支
# 檢視分支
git branch -v
# 新建分支
git branch branch-name
# 切換分支
git checkout branch-name
git checkout -b branch-name # 新建並切換到該分支
# 分支合併到master
git checkout master
git merge branch-name
# 刪除
git branch -d branch-name
git branch -D branch-name # 強制刪除
git branch --merged # 已經被併入到當前分支
git branch --no-merged # 沒有被併入到當前分支
# 推送分支到遠端倉庫
git push remote-name local-branch-name:branch-bane
# 檢出遠端倉庫的分支到本地
git checkout -b local-branck-name remote-name/branch-name
# 跟蹤遠端倉庫
git checkout --track remote-name/branch-name
# 刪除遠端分支
git push remote-name :branch-name
# 衍合
# !!! 永遠不要衍合那些已經推送到公公倉庫的更新
# 回到兩個分支的共同祖先,提取所在分支每次提交時產生的差異,把這些差異分別儲存在臨時檔案中,然後從當前分支轉換到需要衍合入的分支,依序施用每一個差異補丁檔案。最後整合的結果沒有任何區別,但衍合能產生一個更為整潔的提交歷史。
git checkout branch-name
git rebase master
小工具
全域性更換電子郵件地址
git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="[email protected]";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
檢視父提交
# ^表示第一個父提交
git show HEAD^
# 第一個父提交的第一個父提交
git show HEAD^^
# 第二個父提交
git show HEAD^2
儲藏(Stashing)
獲取工作目錄的中間狀態,將其儲存到一個未完結變更的堆疊中,隨時可以重新應用。
# 向堆疊中推送一個儲存
# 可以在執行命令之前和之後使用 git status 檢視
git stash
# 檢視現有儲存
git stash list
# 應用儲存
git stash apply
git stash apply stash@2
git stash apply --index # 重新應用被暫存的文章
Git 內部原理
Git是一套內容定址檔案系統,在此之上提供了一個VCS使用者介面
Git中存在三個物件,分別是tree,commit,blob物件,分別儲存目錄樹,提交資訊,檔案物件。
commit物件格式很簡單:指明瞭該時間點專案快照的頂層樹物件、作者/提交者資訊以及當前時間戳、一個空行、以及提交註解資訊。
為每份內容生成一個檔案,取得該內容與頭資訊的SHA-1校驗和,建立以該校驗和前兩個字元為名稱的子目錄,並以剩下的38個字元為檔名(儲存至子目錄下)
生成 -> git cat hash-object -w filename
解析 -> git cat-file -p 校驗碼
這些物件資訊儲存在.git/objects下
在.git/refs下儲存了檔案的引用資訊,包含分支,master等
.git/HEAD中儲存了最後一次提交的SHA-1值
git往磁碟儲存物件時預設使用的格式叫鬆散物件格式,不定時將這些物件打包至一個叫packfile的二進位制檔案以節省空間並提高效率,當倉庫中有太多的鬆散物件、手工呼叫git gc命令或者推送至元亨伺服器時,Git都會這樣做。
git會不定時的自動執行稱為auto gc的命令,大部分情況下該命令什麼都不處理,存在太多鬆散物件或packfile(7000的左右的鬆散物件或者50個以上的packfile),git會進行呼叫git gc命令,收集所有鬆散物件並將他們儲存packfile,合併packfile進一個大的packfile,然後將不被任何commit引用並且已經存在一段時間(數月)的物件刪除。