【Git实战】从“代码冲突”到“分支管理”:新手避坑完全指南

前言:为什么 Git 总是报错?

很多刚接触 Git 和 GitHub 的朋友,通常的操作路径是这样的:

  1. 本地写代码 -> git add . -> git commit -> git push
  2. 一切顺利,直到有一天发生了下面的事情:
    • 发现 GitHub 上有个叫 main 的分支,本地却叫 master,看着很难受。
    • 手痒在 GitHub 网页上改了个错别字,回家再 Push 本地代码时,报错了!

这篇博客将深入浅出地讲解这两个场景背后的原理,教你如何解决冲突,并掌握真正的分支开发流程。
在这里插入图片描述


场景一:由于历史原因导致的“命名战争” (master vs main)

1. 事故现场

你在本地初始化项目 git init,默认分支通常叫 master
你在 GitHub 创建新仓库,现在的 GitHub 默认分支叫 main
当你关联远程仓库并尝试推送时,由于名字不一致,你可能会把本地的 master 推送上去,导致 GitHub 上同时存在 mainmaster 两个分支,非常混乱。

2. 为什么会这样?

这其实是历史遗留问题。Git 诞生之初默认分支叫 master。但在 2020 年左右,为了政治正确(避免 Master/Slave 隐喻),GitHub 将默认分支改为了 main。但你本地安装的 Git 工具可能默认配置还是 master

3. 最佳解决方案:让本地“归顺”远程

不要去折腾删除远程分支,最简单的做法是把本地的 master 重命名为 main,然后强行覆盖关联。

操作步骤:

  1. 重命名本地分支
    在你的项目根目录下,执行以下命令,将当前的 master 改名为 main

    git branch -m master main
    
  2. 查看所有分支

    $ git branch -a 
    
  3. 删除远程分支master

$ git push origin --delete master 
  1. 切换到当前分支main,也就要保留下来的分支
$ git checkout main

5.合并分支

$ git merge remotes/origin/main 

如果拒绝合并,需要忽略这个限制,添加“–allow-unrelated-histories”

$ git merge remotes/origin/main --allow-unrelated-histories 

6.提交修改

$ git push origin main 

补充:一劳永逸的设置
为了避免以后每个新项目都要改名,建议修改 Git 的全局配置,让以后 git init 的默认分支都叫 main

git config --global init.defaultBranch main

场景二:最常见的“Push 失败” (Remote Rejected)

1. 事故现场

这是新手最容易崩溃的时刻。

  • 动作 A:你在公司(或者直接在 GitHub 网页端)修改了 README.md,增加了一行说明,并保存了。此时,远程仓库的版本比你本地的新。
  • 动作 B:回家后,你打开电脑,继续开发功能,修改了 code.py,然后提交(Commit)。
  • 动作 C:你执行 git push

结果:报错!

 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/...'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.

2. 原理分析:平行宇宙

Git 是分布式的。

  • 远程宇宙(GitHub):已经有了“修改 README”这个历史记录。
  • 本地宇宙(你的电脑):没有“修改 README”的记录,但有了“修改代码”的记录。

此时,两个宇宙的时间线分叉了。Git 也是为了保护你,它不敢贸然把你的代码推上去,因为它怕你覆盖掉远程已有的修改。Git 的原则是:你必须先拥有远程所有的历史,才能在这个基础上增加你的新历史。

3. 解决方案:先拉取(Pull),再推送(Push)

口诀:Push 前必 Pull

情况 A:修改的文件不同(自动合并)

如果远程改的是 A 文件,你本地改的是 B 文件,Git 非常聪明,会自动把两者合并。

# 1. 拉取远程代码并尝试合并到本地
git pull origin main

# 此时 Git 会自动弹出一个编辑界面让你输入合并日志(通常直接 :wq 保存退出即可)
# 或者 Git 自动就完成了 Merge

# 2. 现在你的本地包含了远程的修改,也包含了你的修改,可以推送到远程了
git push origin main
情况 B:修改了同一行代码(代码冲突 Conflict)

这是噩梦级别,但必须面对。如果远程改了 main.py 第 5 行,你也改了 main.py 第 5 行,git pull 时会报错:
CONFLICT (content): Merge conflict in main.py

解决步骤:

  1. 打开代码编辑器:你会发现冲突的文件里出现了奇怪的符号:

    <<<<<<< HEAD
    print("这是我本地写的代码")
    =======
    print("这是远程(GitHub)上的代码")
    >>>>>>> 1234567890abcdef...
    
  2. 人工决定
    你需要手动删除 <<<<, ====, >>>> 这些符号,保留你想要的代码(或者两者都保留)。
    修改后:

    print("这是我本地写的代码,但我看了一下远程的也不错,综合一下")
    
  3. 提交更改

    git add main.py
    git commit -m "解决了代码冲突"
    git push origin main
    

场景三:进阶——为什么需要分支(Branch)?

你提到对分支不太了解。其实,在成熟的开发团队中,几乎不允许直接在 main 分支上写代码

1. 为什么?

main 分支代表生产环境(随时可以发布给用户的版本)。如果你正在开发一个新功能,写到一半代码报错,如果不小心 Push 到了 main,队友拉下来后项目就跑不起来了,甚至可能把线上搞挂。

2. 标准开发流程(GitHub Flow)

假设你要开发一个“登录功能”:

  1. 创建分支:基于 main 创建一个新分支。

    # 创建并切换到 feature-login 分支
    git checkout -b feature-login
    
  2. 疯狂开发:在这个分支上随意修改、提交,就算代码跑不通也没关系,因为 main 分支是安全的。

    git add .
    git commit -m "完成了登录页面的UI"
    
  3. 推送到远程分支
    注意,这里不是推送到 main,而是推送到远程的同名分支。

    git push origin feature-login
    
  4. 发起 Pull Request (PR)

    • 打开 GitHub 网页。
    • GitHub 会提示你“feature-login had recent pushes”。
    • 点击 “Compare & pull request” 绿色按钮。
    • 写上描述:“我做好了登录功能,请求合并进 main”。
  5. 代码审查与合并 (Merge)

    • 你自己(或你的组长)在 GitHub 网页上查看代码变化。
    • 确认没问题后,点击 “Merge pull request”
    • 此时,GitHub 会自动把你的代码合并到 main 分支。
  6. 收尾
    回到本地电脑,切换回 main,拉取最新代码。

    git checkout main
    git pull origin main  # 把刚才在网页上合并好的代码拉下来
    git branch -d feature-login # 删除本地已完成的开发分支(可选)
    

总结:常用命令速查表

为了方便你日常查阅,我整理了这个 Cheat Sheet:

场景 常用命令 备注
初始化 git init
查看状态 git status 最常用的命令,不知道发生什么时就敲一下
切换/创建分支 git checkout -b <分支名> 创建并切换
切换分支 git checkout <分支名>
查看所有分支 git branch -a 包含本地和远程
改名分支 git branch -m <旧名> <新名> 常用于 master -> main
暂存并提交 git add . + git commit -m "..."
同步远程代码 git pull origin <分支名> Push 前必须做
推送到远程 git push origin <分支名>
查看日志 git log --oneline --graph 查看提交历史树

给开发者的最后建议

  1. 不要畏惧报错:Git 的报错通常非常详细(虽然是英文),仔细阅读 hint 部分,通常答案就在里面。
  2. 勤提交:不要写了一整天代码才 Commit 一次。完成一个小功能点就 Commit 一次,这样出问题好回退。
  3. 拥抱 Pull Request:即使是你一个人的项目,也尝试使用“新建分支 -> 开发 -> 提 PR -> 合并”的流程。这会让你养成非常好的职业习惯,面试时也是加分项。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐