1、创建个人分支

上游仓库 ------fork------> 远程个人分支

                                               |

                                              V

                                     本地个人分支(配置上游仓库)

 本地个人分支 `.git/config` 文件,配置上游仓库:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = http://ip:port/XXX/abc.git                    # 上游仓库fork出来的分支
        fetch = +refs/heads/*:refs/remotes/origin/*
[remote "upstream"]
        url = http://ip:port/YYY/abc.git                    # 上游仓库
        fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "main"]
        remote = origin
        merge = refs/heads/main

2、拉取、提交代码的整体流程

远程公共分支 <------PR------ 远程个人分支
               \                               ^
                 \ fetch               /  push
                  V                        /  
                     本地个人分支

3、本地修改后提交代码的命令序列

(1)git stash

暂存本地修改

(2)git fetch upstream

下载上游仓库的更新,但不合并到本地分支

(3)git rebase upstream/main

将上游仓库的更新合并到本地当前分支,使用 rebase 方式

(4)git stash pop

恢复暂存的修改,可能有冲突,需要解决冲突,见下文

(5)git add .

(6)git commit -m "XXX"

(7)git push

(8)创建PR

4、git stash pop 冲突解决

(1)冲突提示

# git stash pop
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
        both modified:   1.txt

no changes added to commit (use "git add" and/or "git commit -a")
The stash entry is kept in case you need it again.

(2)查看冲突文件内容

# cat 1.txt
line1
line2
<<<<<<< Updated upstream
line3
=======
line4
>>>>>>> Stashed changes

冲突说明:
line3 是工作目录中的内容
line4 是stash 中的内容

(3)编辑文件,解决冲突

编辑 1.txt ,选择要保留的内容

选项1:保留工作目录的内容(删除 stash 内容)
line1
line2
line3

选项2:保留 stash 的内容(删除工作目录内容)
line1
line2
line4

选项3:手动合并两者
line1
line2
line3
line4

(4)标记冲突已解决

# git add 1.txt
# git status 

On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   1.txt

# git commit -m  "resolve stash pop conflict"
# git push
# git stash drop        # 删除当前 stash entry(pop 有冲突时 stash entry 依然保留)

5、上游仓库若包含 submodule

(1)初始化本地个人分支时,需要添加 submodule 相关参数

​
git clone --remote-submodules --recurse-submodules http://ip:port/XXX/abc.git

​

(2)拉取上游仓库代码,合并到本地分支

git fetch upstream --recurse-submodules  # 递归处理子模块
git rebase upstream/main
git submodule update --recursive --remote --rebase

也可以修改 .git/config 文件,获取上游仓库时自动处理 submodule

初始 config 文件:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true

[submodule]
        active = .
        
        
[remote "origin"]
        url = http://ip:port/XXX/abc.git 
        fetch = +refs/heads/*:refs/remotes/origin/*
        
[remote "upstream"]
        url = http://ip:port/YYY/abc.git
        fetch = +refs/heads/*:refs/remotes/upstream/*

[branch "main"]
        remote = origin
        merge = refs/heads/main
        vscode-merge-base = origin/main

[submodule "path/to/submodule"]
        url = http://ZZZ.git

修改后:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true

[submodule]
        active = .
        recurse = true                 # 启用子模块递归
        
[remote "origin"]
        url = http://ip:port/XXX/abc.git 
        fetch = +refs/heads/*:refs/remotes/origin/*
        
[remote "upstream"]
        url = http://ip:port/YYY/abc.git
        fetch = +refs/heads/*:refs/remotes/upstream/*
        
[branch "main"]
        remote = origin
        merge = refs/heads/main
        vscode-merge-base = origin/main
        
[submodule "path/to/submodule"]
        url = http://ZZZ.git
        active = true                    # 标记该子模块为"活跃"状态,Git 应该处理它
        update = rebase                  # 子模块更新时使用 rebase

[fetch]                                # 新增 fetch 配置节
        recurseSubmodules = on-demand    # 获取时递归处理子模块,仅当子模块引用改变时才获取

[pull]                                 # 新增 pull 配置节
        recurseSubmodules = yes          # pull 时递归处理子模块
git fetch upstream                      # 自动递归处理子模块(因为配置)
git rebase upstream/main                # 不会自动更新工作目录中的子模块文件

# #必须执行下面两个命令之一,更新子模块工作目录
git submodule update --recursive
git submodule update --recursive --remote --rebase

# --recursive: 递归处理嵌套子模块
# --remote:    更新到远程分支最新,而不是主仓库记录的提交
# --rebase:    如果子模块有本地修改,用 rebase 方式更新
# 注意:--remote 可能会更新到比主仓库记录更新的版本!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐