Git簡介與使用
Intro
Git is a free and open source distributed version control system designed to handle everything from small to very
large projects with speed and efficiency.
Git是一款分布式版本控制系統(VSC),是團隊合作開發的必備工具。
Git Repository 本地可劃分為3個區域:
- workspace
- staging area
- local repository
其交互示意圖如下:
git基本的命令操作可以參看:Git教程
Using within Jetbrains IDE
Jetbrains全家桶提供了對Git的支持,下面以IDEA 2024.1.4
版本演示Git基本操作。
IDEA使用不同的顏色表明文件在Git中的狀態,如下所示為Darcula主題下顏色的含義:
具體顏色含義可參看:Check file status
rollback
如果我本地改動了文件,但發現改動無效,想回到改動之前的文件狀態,可以右擊文件 -> Git -> Rollback
:
commit & amend commit & commit checks
使用IDEA commit窗口可以方便地選擇需要commit的文件,填寫commit信息。此外如果上一次commit有東西忘寫了,這次寫完使用amend
commit將上次和這次改動合并成一次commit,在commit窗口勾選amend即可。
每次commit前需要有些前置校驗呢?比如自動格式化代碼、自動checkstyle,IDEA也提供了該項功能:在commit窗口,點擊設置圖標,勾選所需checks
1.設置 | 2.勾選 |
---|---|
![]() | ![]() |
squash commit
如果我們要將多次提交合并成一個提交,可以定位到當前本地分支,并多選多條commit進行squash:
此時push就需要強制push了
rebase
當master代碼有變動時,基于老master版本開發的本地feature分支需要rebase到最新代碼(即把master分支新代碼合并到本地feature開發commit之前),使用IDEA操作:
- 拉取master最新代碼 git pull
- 切換到feature分支
- 執行rebase
1. 拉取master最新代碼 | 2.執行rebase |
---|---|
![]() | ![]() |
cherry-pick
合作開發時,比如A同學在feature-a
分支開發功能,B同學在feature-b
分支開發,且feature-b
分支依賴feature-a
分支的功能,即feature-b
分支基于feature-a
分支的commit開發。
如果feature-a
分支的commit有改動,則feature-b
就要同步這些改動,且需要保證feature-b
分支的commit不會凌亂,這時可使用cherry-pick來完成。
- 拉取
feature-a
最新代碼; - 復制分支
feature-b
到feature-b-bak
; - 對
feature-b
執行reset --hard
到feature-a
的最早commit之前的一次commit; - 在
feature-b
中cherry-pick
新的feature-a
的commit - 在
feature-b
中cherry-pick
復制的feature-b-bak
的自己的commit
reset --hard | cherry-pick |
---|---|
![]() | ![]() |
ref
- Boost Your Productivity: 13 Pro Git Tips for JetBrains IDEs
Git存儲原理
git中有三種類型的文件:
- blob: 壓縮存儲的二進制文件內容
- tree: 表示項目文件夾,tree下包含subtree和blob,以及blob對應文件的文件名、訪問權限等信息,使用Merkel Hash Tree數據結構構建
- commit: 包含指向的tree和提交信息
3種類型文件均存儲于./.git/objects/
文件夾下,利用40位的SHA的hash值的前2位作為文件夾,后38位作為文件名,其組織形式如下圖:
假設git項目文件夾下有一個a.txt文件,執行完git add .
和git commit -m "first commit"
后./.git/objects/
文件夾新增3個objects:
.git
> watch -n .5 tree .git
...
├── objects
│ ├── 08
│ │ └── 585692ce06452da6f82ae66b90d98b55536fca
│ ├── 47
│ │ └── d94322168b96993a93f2346c8eafd50bcc8317
│ ├── 78
│ │ └── 981922613b2afb6025042ff6bd878ac1994e85
|...
而分支是指向commit hash的一個引用,其存儲在 .git/refs/heads/
下:
> pwd
/Users/bty/IdeaProjects/testgit/.git/refs/heads
> ls
feature-a main
> cat main
47d94322168b96993a93f2346c8eafd50bcc8317
HEAD
表示當前的分支,指向 .git/refs/heads/
的一個文件:
> pwd
/Users/baotingyu/IdeaProjects/testgit/.git
> ls
COMMIT_EDITMSG config hooks info objects
HEAD description index logs refs
> cat HEAD
ref: refs/heads/feature-a
objects文件類型可通過git cat-file -t [40位hash]
查看:
> git cat-file -t 78981922613b2afb6025042ff6bd878ac1994e85
blob> git cat-file -t 08585692ce06452da6f82ae66b90d98b55536fca
tree> git cat-file -t 47d94322168b96993a93f2346c8eafd50bcc8317
commit
以上文件的內容均可以通過git cat-file -p [40位hash]
:
# 查看一個blob,顯示文件內容(不包含文件名,訪問權限等信息,都在tree里面)
> git cat-file -p 78981922613b2afb6025042ff6bd878ac1994e85
a# 查看一個tree,顯示tree下的內容(子tree或blob)
> git cat-file -p 08585692ce06452da6f82ae66b90d98b55536fca
100644 blob 78981922613b2afb6025042ff6bd878ac1994e85 a.txt# 查看一個commit,包含指向的tree和提交信息
> git cat-file -p 47d94322168b96993a93f2346c8eafd50bcc8317
tree 08585692ce06452da6f82ae66b90d98b55536fca
author bty <bty@com> 1720876267 +0800
committer bty <bty@com> 1720876267 +0800first commit