收藏

深入理解 Git: 常见问题解决

2021-11-18  本文已影响0人  my_passion
脑图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

压缩后的 文件内容, 不存 文件名

image.png

2. tree object

文件夹

image.png

3. commit object

树对象封装

含 
    提交 时间 / 作者 等信息
    parent commitID
=> 可形成 

git commit有向无环图

image.png

4 .git/objects 目录

存 3 种 object 的 数据

image.png

2 一切皆 commit

通过 git 命令 理解 git, 处理 git 中 所遇问题

// 名词
commit / branch / tag / HEAD

// 动词
rebase / reset / revert / stash / cherry-pick

2.1 名词

1. commitId branch HEAD tag

image.png
commit 
    commitId: 40位 hash 值 (SHA-1)
    branch  : 指向 指定    分支 last commit 
    HEAD    : 指向 current 分支 last commit
    tag     : 指向 tag 相应的        commit
    
4者 都是指向 `某个 commit` 的 `引用/指针`
=> 一切皆 commit

HEAD^ == HEAD~1 往前倒 1个

image.png image.png image.png

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

image.png

2) user2: fetch + merge

image.png image.png

3) user3 pull

image.png

(2) local branch commit (=> 与 remote-tracking branch divegent ) + merge conflict

1) user1: push

image.png

2) user2: commit -> fetch

image.png

3) user3: commit ( 与 最新的 remote 修改 同一文件同一部分 ) -> pull -> merge conflict

image.png

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) commitcurrent 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
上一篇下一篇

猜你喜欢

热点阅读