梳理一下标准流程:
一、正常的工作流程(避免冲突)
1. 初次获取仓库(只需一次)
git clone <仓库地址>
cd <仓库目录>
之后就不需要再 clone 了,直接进入已有的本地仓库目录工作。
2. 每次开始工作前,先同步远程最新代码
git pull --rebase origin master
或者普通的合并方式:
git pull origin master
推荐使用 --rebase 保持线性历史,减少不必要的合并提交。
如果远程没有更新,git pull 会直接告诉你已经是最新的。
3. 修改文件,然后提交
git add .
git commit -m "描述你的修改"
4. 推送前(可选)检查状态
git log --oneline --graph --decorate --all -20
或者更简单地:
git status
确认本地和远程是否分叉。如果 git pull 之后没有再出现新的远程提交,通常不会分叉。
5. 推送到远程
git push -u origin master
-u参数只在第一次推送时需要,用来设置上游分支,之后可以直接git push。- 如果远程没有新提交,你的推送一定是快进(fast-forward),不会报错。
二、如果推送时遇到“non-fast-forward”错误
这说明远程有本地没有的提交,也就是远程在你上次拉取后又有了新提交(别人推的,或者你在 GitHub 网页上操作产生的)。此时需要先整合远程的提交。
解决方法(推荐 rebase)
-
拉取远程提交并变基
git pull --rebase origin master- 这个命令会自动把远程的提交拉下来,然后把你的本地提交“嫁接”到远程最新提交之后。
- 如果没有冲突,命令会顺利结束,此时你的本地历史已经包含了远程提交,且你的提交在最新位置。
- 注意:如果
git pull --rebase已经成功完成,就不需要再执行git rebase --continue。
-
如果出现冲突,Git 会暂停并提示冲突文件。你需要:
- 手动编辑冲突文件,删除冲突标记(
<<<<<<<、=======、>>>>>>>),保留正确内容。 - 执行
git add <冲突文件>或git add .标记为已解决。 - 继续变基:
git rebase --continue - 重复直到变基完成(提示 “Successfully rebased and updated refs/heads/master.”)。
- 手动编辑冲突文件,删除冲突标记(
-
推送
git push origin master此时因为本地已经包含了远程的所有提交,是快进推送,不会报错。
三、澄清你的表述
你说:“如果遇到有其他人基于某分支的提交,导致我们拉取的版本在提交时会弹出冲突,即两个提交都基于同一分支提交,就先变基git pull –rebase origin master,然后git rebase –continue,最后git push -u origin master?”
这里有一个小误区:
git pull --rebase origin master本身就会执行变基操作。如果变基过程中出现冲突,它不会自动完成,而是停下来让你解决冲突。解决冲突后你需要执行git rebase --continue来继续变基。- 所以顺序是:
git pull --rebase origin master(可能因冲突而暂停)- 解决冲突 →
git add . git rebase --continuegit push origin master(不需要再加-u,除非是第一次推送该分支)
如果 git pull --rebase 没有冲突,它就直接完成了,不需要 git rebase --continue。
四、总结推荐的标准工作流
# 1. 进入仓库目录(不是每次clone)
cd your-repo
# 2. 同步远程最新代码
git pull --rebase origin master
# 3. 修改文件...
# 4. 提交
git add .
git commit -m "你的提交信息"
# 5. 推送
git push origin master # 第一次可用 git push -u origin master
如果推送时发现被拒绝(因为远程有新提交),回到第2步执行 git pull --rebase 再推送。
这样就能避免绝大多数“非快进”错误,也能保持提交历史整洁。
五、强制推送回退
git commit –amend:只适用于 “刚写完代码,还没 push” 的情况。作用是 “替换” 上一次提交。
它不是用来提交的。如果你add一次新的改动,然后输入这个命令,会看到的上一次commit信息,如果你修修改改提交了,会出现阻止信息。
如果应对这次阻止你直接输入了——
git push --force-with-lease origin master
强制推送以恢复远程,会覆盖掉上一次提交信息。
遇到这个情况你需要在本地输入命令以查看操作日志,找到被 amend 之前的那个提交哈希值(比如叫 a1b2c3d)
# 1. 查看操作日志,找到被 amend 之前的那个提交哈希值(比如叫 a1b2c3d)
git reflog
## 这条命令对比旧提交(708cd3f)和新提交(0f50a4c),把差异存成补丁
git diff 708cd3f 0f50a4c > my_changes.patch
# 2. 把本地分支强行指回那个哈希值(恢复第4次)
git reset --hard a1b2c3d
# 3. 把被覆盖掉的提交重新推回远程,恢复远程的历史
git push --force-with-lease origin master
# 4.把你刚才备份的补丁,应用到当前代码上
git apply my_changes.patch
(如果这一步提示冲突,别怕,那是因为补丁里的内容和你现在的代码略有偏差,手动把补丁里的修改重新加进去就行,通常不会)
我的建议是最好清除当前本地文件夹除了.git外的其他所有文件,把本地的备份拿过来放进去。
# 5. 正常提交成为第5次
git add .
git commit -m "这是新增的第5次提交"
git push origin master
六、提交
通常我们见到的git commit -m是跳过编辑器,直接把这句引号里的内容作为提交信息。
如果我们想编辑提交内容应该git commit,它会弹出一个文本编辑器(黑框里的 Vim 或 Nano),让你在里面写长篇大论的提交说明。
此时编辑器会出现一堆以#号开头的文字,这些都是注释说明不会出现在提交信息里。我们输入命令后会默认进入INSERT插入模式,光标来到第一行这个空行。你将提交信息粘贴进编辑器即可。
若想清空编辑器信息,Windows系统可以按Esc键,输入vim快速删除全部内容的命令ggdG然后回车,在输入i回到插入模式。
输入完成后按Esc键,输入!wq回车,提交就完成了。