深入理解 Git: 常见问题解决
脑图1: Git objects
1. blob object: 压缩后的 文件内容, 不存 文件名
/
| 2. tree object: 文件夹
Git objects | (1) 树对象 的 封装
/
| | 提交 时间 / 作者 等信息
/
| 3. commit object |—— (2) 含
\
| | parent commitID
\
| (3) 可形成 git commit 的 有向无环图
\
4. .git/objects 目录 : 存 3 种 object 的 数据
脑图2: 一切皆 commit
commitId: 40位 hash 值 (SHA-1)
branch : 指向 指定 分支 last commit
HEAD : 指向 current 分支 last commit
tag : 指向 tag 相应的 commit
/ 4者 都是指向 `某个 commit` 的 `引用/指针`
/ => 一切皆 commit
1. commit
/ \
/ \
| HEAD^ == HEAD~1 往前倒 1个
| local repo 中 指向 与 remote repo 最后一次 同步 时, 相同的 commit
/
|—— 2. origin/branch: remote-tracking branch
\
与 remote 交互时, 更新
一切皆 commit |
| git fetch origin dev: 使 remote-tracking branch origin/dev 与 remote branch dev 同步
/
|—— 3. fetch / pull
\
| git pull origin dev = git fetch origin dev + git merge origin/dev (将 remote-tracking branch origin/dev 合并到 local branch)
pull 的 自动 merge 可能 merge conflict
|
方法1:
| ( fut ) $ git checkout dev
( dev ) $ git pull
| / ( dev ) $ git checkout fut
/ ( fut ) $ git merge dev
/
|—— 4. 当前 在 fut 分支, 现在需 合并 最新 dev 分支
\
| \
\ 方法2: 不用 切到 dev 分支
|
`同步 remote-tracking branches 的 所有 ( 含 dev ) 分支`
| + 合并 `remote-tracking branch origin/dev` 到 `local fut 分支`
| ( fut ) $ git fetch
( fut ) $ git merge origin/dev
|
(1) `所有代码: merge`
| (currentBranch)$ git checkout master( master )
/ ( master ) $ git merge dev
/
|—— 5. 合并 `一个分支` 到 `另一分支`: 合并
\
| \
(2) `某个 commit: cherry-pick`
| (currentBranch) $ git checkout master
( master ) $ git cherry-pick C3
|
\ step1: `git reflog` 查 commit history, 找 被删 branch 中 指定 commit
\ /
6. 2 次 提交 -> 删分支 -> 发现 刚才 2个 提交有价值, 怎么找回来
\
step2: `git cherry-pick` 移 被删 branch 中 某 commit 到 current branch
1 Git 底层对象
git 本质: 内容寻址 文件系统
key: 哈希值
/
key -value 数据存储
\
value: content
1. blob object
压缩后的 文件内容, 不存 文件名
2. tree object
文件夹
3. commit object
树对象
的 封装
含
提交 时间 / 作者 等信息
parent commitID
=> 可形成
git commit
的 有向无环图
4 .git/objects 目录
存 3 种 object 的 数据
2 一切皆 commit
通过 git 命令 理解 git, 处理 git 中 所遇问题
// 名词
commit / branch / tag / HEAD
// 动词
rebase / reset / revert / stash / cherry-pick
2.1 名词
1. commitId branch HEAD tag
commit
commitId: 40位 hash 值 (SHA-1)
branch : 指向 指定 分支 last commit
HEAD : 指向 current 分支 last commit
tag : 指向 tag 相应的 commit
4者 都是指向 `某个 commit` 的 `引用/指针`
=> 一切皆 commit
HEAD^ == HEAD~1 往前倒 1个
2. origin/branch: remote-tracking branch ?
local repo
中 指向 与 remote repo 最后一次 同步
时, 相同的 commit
何时 `更新` ?
`与 remote 交互时`, 即 `fetch / pull / push 时`
2.2 动词
1. fetch / pull
git fetch origin dev: 使 remote-tracking branch origin/dev 与 remote branch dev 同步
git pull origin dev = git fetch origin dev + git merge origin/dev (将 remote-tracking branch origin/dev 合并到 local branch)
(1) local branch 未 commit => 与 remote-tracking branch 未 divergent
1) user1: push
2) user2: fetch + merge
3) user3 pull
(2) local branch commit (=> 与 remote-tracking branch divegent ) + merge conflict
1) user1: push
2) user2: commit -> fetch
3) user3: commit ( 与 最新的 remote 修改 同一文件同一部分 ) -> pull -> merge conflict
2. 当前 在 fut 分支
, 现在需 合并 最新 dev 分支
, 方法?
(1) 方法 1
( fut ) $ git checkout dev
( dev ) $ git pull
( dev ) $ git checkout fut
( fut ) $ git merge dev
(2) 方法2: 不用 切到 dev 分支
`同步 remote-tracking branches 的 所有 ( 含 dev ) 分支` +
合并 `remote-tracking branch origin/dev` 到 `local fut 分支`
( fut ) $ git fetch
( fut ) $ git merge origin/dev
3. git reset --soft <commit>
`not touch index` file nor `working tree`
`resets head to <commit>`
=>
leaves all `changed` files "Changes to be committed"
4. cherry-pick 移(不删) 花接玉
需求: 合并 `一个分支` 到 `另一分支`
2 种情况
合并 `所有代码 / 某个 commit: merge / cherry-pick`
( current branch ) $ git cherry-pick <commitId>
合并 (可以是 other branch) commit
于 current branch
, 在 current branch 产生 新 commit
C - C1 master
\
C2 - C3 - C4 dev
(1) merge
# 切到 master 分支
$ git checkout master
# merge
( master ) $ git merge dev
// merge
C - C2 - C3 - C4 - C1 - CMerge master
\
C2 - C3 - C4 dev
(2) cherry-pick
# 切到 master 分支
$ git checkout master
# cherry-pick
( master ) $ git cherry-pick C3
// cherry-pick
C - C1 - ( + C3 ) = C5 master
\
C2 - C3 - C4 dev
image.png
image.png
应用: 2 次 提交 -> 删分支
-> 发现 刚才 2个 提交有价值, 怎么找回来
?
1) git reflog 查 commit history, 找 被删 branch 中 指定 commit
2) git cherry-pick: 移 被删 branch 中 某 commit 到 current branch
image.png