1. 程式人生 > 實用技巧 >Git 學習雜記

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引用並且已經存在一段時間(數月)的物件刪除。