在自己一个使用 git 来管理项目时,可能使用 git push git pull git commit 等等常用指令就可以,但是一旦融入到团队中,git 就会复杂起来,下面介绍了一些在团队协同开发的时候常用的 git 操作。
分支
主分支的要跟远程仓库保证一致,当我们接到一个新的代码修改任务时,正确的步骤是这样的:
- 切回主分支
git checkout main - 拉取远程最新代码
git pull origin mian - 基于最新的
main创建新的分支,新的分支最好做到见名知义,直接指向这个修改所要达成的目的git checkout -b feature/user-login
Git 分支命名约定:
在分支名中使用前缀和描述性部分两部分,中间使用/隔开。常用的前缀有:feature/用于开发一个新功能bugfix/用于修复一个 Bugrelease/用于准备版本发布docs用于编写、更新或修复文档https://medium.com/@abhay.pixolo/naming-conventions-for-git-branches-a-cheatsheet-8549feca2534
拉取远程仓库
拉取仓库中的内容有两种方式,分别是 git fetch 和 git pull
git pull 非常直接,会直接要求我们将代码冲突解决并完成合并。
gti fetch 并不会直接将代码与我们的分支进行合并,而是会放入到一个叫做 origin/master 的分支中,我们可以使用git diff HEAD origin/master 来查看当前代码和远程的差异,确定没有问题后,再 marge 到现在的分支中即可。
所以我们也可以认为:git pull = git fetch + git merge origin/master
在 IDEA 中使用该操作
以下的内容来自 Gemini:
按照 Fetch(抓取) -> Compare(透视) -> Merge(合并) 的“安全着陆”三部曲来操作。
第一步:Fetch
在 IDEA 里,这一步非常简单,动作虽小,但意义重大。
- 操作位置:
- 顶部菜单栏: 点击
Git->Fetch。- 或者(常用): 在 IDEA 窗口右上角的 Git 组件区域,或者左上角的“Commit”面板附近,通常有一个 向下的蓝色箭头(注意:有些版本这个箭头直接是 Update Project,建议先用菜单的 Fetch 确保万无一失)。
- 快捷键: 如果你是快捷键党,可以搜索
Fetch绑定一个(默认可能没有)。- 效果:
- 点击后,界面通常只会闪一下进度条。
- 这时候,你的代码界面不会有任何变化(这就是安全感的来源)。
- 但是在后台,IDEA 已经把远程最新的代码更新到了
origin/master(或者origin/main)这个“影子分支”上。
第二步:Compare
这个时候,我们要看看老王到底改了什么,是不是埋了雷。
- 打开 Git 视窗:
- 按快捷键
Alt + 9(Windows) /Cmd + 9(Mac),打开底部的 Git 工具窗口。- 点击
Log标签页。- 观察“分叉”:
- 你会看到 Git 的提交历史线。
- 找那个 黄色/绿色的标签
origin/master。- 如果刚才 Fetch 下来了新代码,你会发现:你的本地
master标签停留在下面,而origin/master标签跑到了上面(更远的时间点)。- 中间这一段差距,就是老王新写的代码。
- 执行“透视” (Compare with Current):
- 在左侧的分支列表(或者直接在 Log 图里的
origin/master标签上),右键点击Remote > origin > master。- 选择
Compare with Current(与当前分支比较)。- 审查差异:
决策: 如果发现有坑,你现在完全可以按兵不动,去群里找人对峙。你的本地代码毫发无损。
- IDEA 会弹出一个文件列表窗口。
- 双击其中任何一个文件。
- 神器出现了: 左边是你的代码,右边是即将进来的代码。差异被高亮显示。
- 此时你可以像做 Code Review 一样:
- “嗯,这个类加了个方法,没问题。”
- “等一下!
Config.java里的version怎么变了?关键配置怎么删了?”
第三步:Merge
如果你审查完代码,确认老王的修改是安全的,或者就算有冲突你也准备好解决了,就可以执行合并。
- 操作:
- 依然是在底部的 Git 窗口或者是分支列表里。
- 右键点击
origin/master。- 选择
Merge 'origin/master' into 'current'。- (如果你是高阶玩家,想保持直线历史,这里可以选择
Rebase 'current' onto 'origin/master')- 结果:
- 这时候代码才会真正进入你的编辑器。
- 如果有冲突,IDEA 会弹出一个非常棒的三栏解决冲突窗口(Three-way merge tool),帮你解决。
总结:IDEA 里的“安全工作流”
养成这个肌肉记忆:
- 早起/饭后:
Git -> Fetch。- 扫一眼:
Alt+9看一眼 Log,看看origin/master是不是跑前面去了。- 点开看: 如果跑前面去了,右键
Compare看看改了啥。- 最后: 确认没事,右键
Merge。
同步
我们在自己的分支开发的过程中,远程仓库很有可能发生的变更,我们就需要将这些变更拉回本地,并且处理可能发生的冲突。
完成合并有两种实现方式,分别是 Merge 和 Rebase
Merge
首先进入要合并的分支 ,执行 git merge master 意思是将远程仓库中的内容同步到我们的分支,此时如果出现冲突,git 会自动为我们生成一个 code.txt 文件,文件中会展示所有的异常,我们可以直接过程 vscode 等提供的图形化页面来解决冲突,也可以手动编辑这个文件,将所有的钻石符给消除,然后git add code.txt , git commit -m "message" ,事实上,就算使用图形化页面,也会经历commit 这一步,这就是为什么我们的提交历史上会多出一个类型于 marge:…… 的提交历史。
rebase
首先进入要合并的分支 ,执行 git rebase master,同样会在出现冲突的时候出现一个code.txt 文件,同样的我们需要要消除这个文件中的异常,并使用git add code.txt 将其暂存,但是,接下来不是 commit ,而是 git rebase --continue
使用这种方式解决冲突后,通过 git log --graph --oneline --all ,可以看到,我们的提交历史是一条直线,并没有分叉。
撤回
git reflog ,他就像 mysql 的回滚日志,是以追加写的方式记录我们执行过的所有操作,并且为每个操作都分配了一个 Hash 值和回滚编号,借助这两者的任意一个都可以回到我们刚执行过这行名字之后的状态。使用流程:
git reflog查看回滚日志git reset --hard hash/编号(HEAD@{1})回退到历史版本
如果只是由于一条误操作指令带来的回退,直接 reset 即可,但是如果操作较为复杂,建议先为当前版本创建一个分支,分支中也会包含一样的 reflog ,然后在分支中检查无误后再进行合并。
暂存
当我们敲代码敲一半不得不去完成另一个任务(比如去修复一个紧急的bug)但是当前的代码有刚刚完成一半,甚至连编译都在爆红,这样的代码肯定是不适合 commit 的这时我们就可以使用 git 的暂存功能。
idea 操作
- git -> Uncommitted Changes -> Stash Changes...
- 在弹出的页面中为我们的暂存起一个名字,一定要说明这项暂存的内容
- 点击
Create Stash,此时我们一半的代码都没了,我们可以放心的切换分支去干别的事了 - 处理完其他的事,回到现在的分支中,点击 Git -> Uncommitted Changes -> Unstash Changes...
- 选择刚刚保存的那个存档
- 这时会出现两个选项:Pop 和 Apply
- Pop : 恢复代码的同时,将这条记录给删除
- Apply : 恢复代码,但是依然保留记录
事实上,当我们在 IDEA 中切换分支时有忘记保存的代码,IDEA 会自动的帮我们 Stash,等我们切回时再 Pop ,但是这个过程可能会发生错误,建议还是手动将代码给暂存一次。
命令行操作
在命令行中其实就是四个指令:
git stash save "message"将当前的代码暂存git stash list查看所有存档git stash pop恢复并删除最后一个存档,也可以在后面加上从 list 那里读到的序号,指定回复存档git stash apply恢复但不删除存档,同理可以多加一个参数。
合并提交
通常为了完成一个功能我们会多次 Commit ,但是在进行 PR 的时候我们可能并不希望将这些零碎的历史一通展示,因此我们可以选择将提交历史进行合并。同样可以使用两种方式进行操作,分别是 IDEA图形化页面和命令行操作。
IDEA(推荐,方便进行编排
找到我们的第一次提交(是第一次,不是第一次的上一次),右键,点击:Interactively Rebase from Here...,通过拖动调整重新提交的顺序,对于想压入的提交,点击对应提交后点击Squash右面的小箭头,选择 Fixup,而 Squash是我们要保留的提交历史,可以点击 Reword 重置提交名,版本完成后点击 Start Reasing 即可
命令行操作
使用 git rebase -i HEAD~n ,其中的 n 就是我们要合并的提交数(最近几个),在弹出的第一个文本页的,将我们想要压入的提交前面的 pick 改为 s ,注意在这里修改提交名是无效的,完成修改后,将这个页面保存,出现一个新的文本页,在这个页中可以修改每个提交的名称。
另外需要注意的是,无论使用哪种方式进行合并,我们合并的都是本地提交且还没有推送的记录,在idea中已经 push 的记录是直接不可选 Interactively Rebase from Here... 的,在命令行中虽然可能强制完成此操作,但是还是会在提交记录中出现一个分叉。
工作流程梳理
开工前: git fetch origin -> 看一眼 Log -> git rebase origin/master (保持基准线最新)。
开发中:
- 正常
add,commit(哪怕是琐碎的提交也没关系)。 - 遇到紧急插队任务:
git stash-> 切分支修 Bug ->git stash pop。
提交前 (Push前):
- 发现自己提交了 5 个琐碎记录? ->
git rebase -i(Interactive Rebase) 整理成 1-2 个清晰的提交。 - 再次确保不冲突 ->
git fetch->git rebase origin/master。
推送: git push origin feature/xxx。
合并: 在网页端(GitHub/GitLab)发起 Pull Request,等待队友 Review。
Comments NOTHING