校招新人们,这份Git操作指南请收好
这篇文章建立在你已经对git有一定的了解程度
如果你不太了解,请戳git学习
前言
每个公司关于git协作开发的规定可能有所不同,本文提到的关于分支的规定只是一种比较简单的规定,用dev和pre两个分支来涵盖测试环境和预发环境。实际上,在复杂的企业项目中,如果将所有的需求开发都放在一个分支中进行提测,将会导致不可预估的后果,比如相互耦合的问题、集成问题、可维护性问题等。一般会采用分支管理策略,将不同的需求分别放在不同的分支中进行开发和测试。这样可以使不同的需求之间相互独立,减少相互耦合的问题,提高开发效率和质量。同时,还可以通过合并分支的方式将不同的需求集成到主分支中,确保整个项目的稳定性和可靠性。
分支管理策略可能会涉及一个泳道
的概念。
在软件开发中,部署泳道(Deployment Lane)是指将软件的不同版本或不同环境部署到不同的服务器或容器中,以确保软件的稳定性和可靠性。通常情况下,开发人员会将软件部署到多个泳道中,例如开发环境、测试环境、预发布环境和生产环境等。每个泳道都有自己的服务器或容器,以确保不同环境之间的隔离和独立性。部署泳道的概念可以帮助开发人员更好地管理软件的不同版本和不同环境,从而提高软件的质量和可靠性。
例如: 假设一个
https://s1-all.dev.example.com
,这个地址的泳道为s1-all.dev,该泳道是用于整体部署的,即包含最后所有的需求部署。针对每个小需求,联调时会进行单独的联调泳道部署,测试时也会进行单独的测试泳道部署。例如https://s1-demand1-union.dev.example.com
、https://s1-demand1-test.dev.example.com
等。
1、关于分支
分支 | 说明 | 用途 |
---|---|---|
dev | 测试环境分支,包含在开发分支自测完成提测的代码。 | QA测试+产品走查 |
pre | 预发环境分支,包含通过dev分支测试且需要在预发环境测试的代码。 | QA预发布前覆盖测试 |
master | 正式环境分支,包含通过dev&pre分支测试且需要发布上线的代码。 | 线上使用 |
fix/[分支名自定义] | bug修复分支,本地开发自测的代码。 | 供个人/多人修复线上bug使用 |
feat/[分支名自定义] | 开发分支,本地开发自测的代码。 | 供个人/多人开发分支 |
2、分支合并不能做的那些事
禁禁禁 dev合并到master
禁禁禁 pre合并到master
禁禁禁 feat/fix分支未测试的代码合并到pre/master
禁禁禁 未跟他人确认覆盖他人代码
- 你永远不知道dev上的代码是否包含别人没有通过测试的代码,所以千万不要合并dev到pre&master。
- 你永远不知道pre上通过测试的代码是否需要发布到线上,所以千万不要合并pre到master。
- 你永远不知道覆盖别人的代码会发生什么事情,请不要这样做。
3、分支开发/合并的正确姿势
创建feat支规则
从最新的master分支上创建新的feat分支
提测dev
合并feat到dev。如果需要修改代码或者修复bug,你可以继续在feat分支开发,再合并到dev。
提测pre
合并feat到pre。如果需要修改代码或者修复bug,你可以继续在feat分支开发,合并到dev,
测试通过后再合并到pre。
发布上线
合并最新的master分支到feat分支,解决可能出现的冲突,再合并feat到master。
如果需要修改代码或者修复bug,你可以从master分支新开一个fix分支,合并到dev,
测试通过后再合并到pre和master。
分支合并
你应该尽量保持feat分支与master分支的一致性,防止一些意想不到的问题。
4、commit message格式
用于说明git commit的类别,feat/fix等value为commit type,冒号后的内容为subject,别忘记:后的空格,不然提交commit会失败。
格式:<type>(<scope>): <subject>
,其中:
type(必须)
feat:新功能(feature)。
fix:修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。
docs:文档(documentation)。
style:格式(不影响代码运行的变动)。
refactor:重构(即不是新增功能,也不是修改bug的代码变动)。
perf:优化相关,比如提升性能、体验。
test:增加测试。
chore:构建过程或辅助工具的变动。
revert:回滚到上一个版本。
build: 打包。
merge:代码合并。
sync:同步主线或分支的Bug。
scope(可选)
scope用于说明 commit 功能所属的模块。
subject(必须)
subject是commit目的的简短描述,不超过50个字符。建议使用中文。
根据以上规范git commit message将是如下的格式(🙈🙈🙈别忘记冒号后的空格🙈🙈🙈):
fix: 修复走查问题
feat(分销系统): 应用商店UI开发
5、关于一些常用的git操作
5-1 关于克隆代码
当你使用git clone
命令时,默认情况下会克隆远程仓库的所有分支并将它们保存在本地仓库中。如果你只想克隆特定的分支,可以使用以下命令:
git clone -b <branch_name> <git_url>
其中, <branch_name>
是你想要克隆的分支名称,<git_url>
是远程仓库的地址。
如果你不指定-b参数,则git clone
会从默认分支(master)进行克隆。所以,如果你想克隆某个特定的分支,就需要使用上述命令来明确指定它。
另外,在克隆完成后,你可以使用以下命令来查看本地仓库中存在的所有分支:
git branch
这个命令可以显示出本地仓库中存在的所有分支列表,包括当前所在的分支。
5-2 关于新建分支进行开发
- 在您本地的代码仓库中,运行
git checkout master
命令,确保当前所在分支为master分支。 - 运行
git pull
命令,将master分支上最新的代码更新到本地。 - 运行
git checkout -b feat/<your_feature_branch> master
命令,新建一个以"feat/
"为前缀的、从最新的master上创建的分支,<your_feature_branch>
是你自己起的分支名。 - 在分支上对代码进行开发,包括修改代码、添加新的文件等等。
- 在完成一定的开发工作之后,使用
git add <filename> 或 git add .
命令将修改的内容添加到暂存区,并使用git commit -m "<commit_message>"
命令提交变更。其中,<filename>
是你想要提交的文件名,<commit_message>
是你对本次提交的注释信息。 - 当完成了所有的开发任务之后,运行
git checkout dev
命令切换至dev分支。 - 运行
git pull
命令,确保本地的dev分支和远程仓库上的dev分支同步。 - 运行
git merge feat/<your_feature_branch>
命令,将你的feature分支合并到dev分支。如果合并成功,将出现"Merge successful"的提示信息。 - 最后,将dev分支上的变更推送到远程仓库中,运行命令
git push origin dev
。
这样操作后,你的修改就会被合并到dev分支中,其他人也可以从远程仓库中拉取最新的代码,包括你所提交的代码。
5-3 关于拉取远程仓库某个分支进行开发
本地项目存在其他分支,此时要拉取远程仓库的某个分支进行开发,执行以下命令:
// 执行完该命令后再执行git checkout <branch>即可切换到新分支
// 再执行git branch即可查看本地已有的分支
git fetch <remote> <branch>
其中,<remote>
是远程仓库的名称,比如 origin
;<branch>
是要拉取的分支名称,比如 master
。
这个命令会将远程仓库的指定分支拉取到本地仓库中,但不会自动合并到当前分支。如果需要将远程分支合并到当前分支,可以使用 git merge
命令。
如果想要将远程分支直接拉取并合并到当前分支,可以使用以下命令:
git pull <remote> <branch>
这个命令相当于先执行 git fetch
,然后再执行 git merge
。
5-4 关于仓库的第一次推送
注意,无论是github还是gitlab,第一次推送的分支都必须为master主分支,对于github,若第一次推送的不是master分支,而是XXX分支,则可能导致XXX分支成为主分支。对于gitlab,第一次推送的不是master分支会被阻止,待master分支完成第一次推送后,本地创建的新分支才能推送上去(第一次必须先执行命令创建远程关联)。
慎用强制提交:git commit -m "xxx: xxxxxxxxxx" --no-verify
5-5 关于暂存修改
如果想拉取远程最新的代码,但自己本地又已经作出了另外的修改,此时便可执行以下命令,实现既拉取远程最新代码的同时又保留自己本地的修改:
- 暂存本地修改:
git stash -u
- 拉取远程分支:
git pull
- 将暂存的本地修改重新pop出来:
git stash pop
干货文章(关键时刻真救命):Git——找回丢失的git stash内容
总结,找回丢失的git stash内容步骤:
git fsck --lost-found
打印出所有的dangling commit
(每次git stash
都会生成一个新的commit)。git show [commitId]
将一条条的去show出这些内容,然后判断是否是要找回的。(因为这些id所对应的记录并不是有序的,重点关注修改内容与日期来找)。- 找到[commitID]之后就去执行
git stash apply [commitId]
恢复工作区。
5-6 关于合并分支
如果想将本地的feature分支合并到仓库的某一个分支(本地没有),以分支dis-4.0为例,需要首先从远程仓库中拉取dis-4.0分支到本地仓库中:git fetch origin dis-4.0:dis-4.0
然后再执行git checkout
切换分支、git pull
拉取分支、git merge
合并分支
此时执行
git push --set-upstream origin dis-4.0
推送上去即可。
5-7 关于版本回退
首先执行git log
查看项目提交信息,可以看到每次推送的哈希值:
然后版本回退有两种方案:
git reset --soft HEAD~n
(回退n个版本)
git reset --hard 6547ef45e94eb2d21c74ee9ec5bb0c928210c307
(回退到某次提交哈希值对应的版本)
--soft 标志表示软重置(soft reset)。软重置将移动 HEAD 指针到指定的提交,但不会更改工作区和暂存区的内容。软重置通常用于撤销之前的提交,而不希望丢失已经做出的更改。
--hard 标志表示硬重置(hard reset)。硬重置直接将你的本地代码重置到该版本,最新的更改会丢失(除非重新pull到本地)。
git reset
要慎用,--hard尤其要慎用。(记得更改要push/stash好,保存下来,否则难找。)
回退版本后可以执行git status
命令来查看当前项目的状态,它可以显示哪些文件已修改,哪些文件已暂存,哪些文件未被 Git 跟踪,以及当前分支的状态等信息。:
5-8 关于撤销更改
git revert
命令用于撤销先前的提交,创建一个新的提交来反转更改。它会生成一个新的提交,该提交将撤销先前提交中引入的更改。
git revert HEAD
表示撤销最近的更改。
git revert <commit-hash>
表示撤销指定提交引入的更改。
git revert -m 1 <commit-hash>
-m 1 表示要撤销合并提交中的第一个父提交。
注意:不要尝试用git revert
命令去撤销某次git merge的更改,这会使得git commit信息具有迷惑性(merge的分支会带来无法清除的commit信息!!!git revert
操作要谨慎!!!)。这种情况应该git reset或者新建一个分支进行代码pick操作,同时建议开发团队接一个gitlab webhook,如果有revert merge的提交直接告警。可看这篇博客学习:谈一谈git revert和revert the revert。
5-9 关于删除分支
一般来说,完成项目的某个需求开发完成后(指的是已经通过测试、已经上线),如果确定自己的开发分支基本不会使用到了,应该选择删除掉该分支,防止仓库中积累过多的无用分支。如若遇到新的需求开发,再从matser分支上新建自己的开发分支,确保代码是最新且没有问题的。删除分支的命令如下:
删除本地分支:git branch -d <branch-name>
强制删除本地分支:git branch -D <branch-name>
删除远程分支:git push origin --delete <branch-name>
6、关于一些常见报错的处理
6-1 关于git第一次配置ssh key,clone代码出错解决
第一次执行git clone拉取代码时遇到问题:
明明配置了ssh key,但是仍然出现上述错误导致无法克隆项目成功。
原因:.ssh文件夹下缺少known_hosts文件,正常如下:
解决方案:Are you sure you want to continue connecting (yes/no/[fingerprint])? 这步问答,不能直接按回车,要输入yes后按回车。
6-2 关于在同一分支协作开发导致推送时报错解决
多人在同一个分支进行开发时,可能会导致推送时报分支冲突的错误,如下图,执行git push
报错导致无法推送远程仓库。
- 原因: 将本地分支推送到远程分支时,本地分支和远程分支存在冲突,需要指定如何合并它们。
- 解决方法: 将远程分支的代码拉取到本地解分支决冲突问题后再进行推送。
可以在下一次 pull 之前运行以下命令之一来解决问题:
git config pull.rebase false
:合并分支git config pull.rebase true
:变基分支git config pull.ff only
:仅快进合并
执行完上述命令之一之后,再执行git pull就可将远程分支拉到本地,此时再去执行git push
就会推送成功了。
6-3 关于ssh: connect to host github.com port 22: Connection timed out
问题: ssh: connect to host github.com port 22: Connection timed out
解决: 在.ssh下面建立config文件,内容如下:注意config无后缀名!
Host github.com
User git
Hostname ssh.github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
Port 443
测试连接情况: ssh -T git@github.com
,回车后看到yes说明成功了。
7、一些命令的区别
7-1 关于git pull和git fetch的区别
git pull
和git fetch
都是用于从远程仓库获取更新的命令,但是有一些区别:
1、git fetch
只是下载远程仓库的对象和引用,不会改变本地工作目录的内容。
2、git pull
则是获取远程仓库的最新提交,并且合并到本地工作目录,可能会产生冲突。
3、git fetch
可以让你在合并之前审查远程仓库的变化,而git pull
则是直接合并,可能会覆盖本地的修改。
7-2 关于git merge和git rebase的区别
git merge
和git rebase
是两个常用的Git命令,它们都用于合并代码分支,但是它们的实现方式以及对代码分支历史记录的影响是不同的。
具体来说,git merge
命令会将两个或多个独立的分支合并到一起,形成一个新的提交节点,并保留原分支的历史记录。这意味着在合并后的分支上,你可以看到所有先前分支的提交历史,包括它们的顺序、时间戳和作者信息等。这种方法适用于合并长期存在的分支,或者在多人协作开发时将多个人的代码更改合并到一起。
相反,git rebase
命令可以在将分支合并到目标分支之前将其“变基”,也就是说将其基于目标分支节点重演。这种方法创建了一个新的提交节点序列,其中包括要合并的分支的提交历史,并在其中插入目标分支的每个提交节点。这有助于使提交历史更加清晰,因为它允许维护单一提交线,并避免了因合并而产生的额外的“合并提交”节点。这种方法适用于需要在本地工作期间对分支进行重构的情况,或者希望保持提交历史记录的整洁和易于理解。
git merge图示:
merge合并将在您的特征分支中将更改集成,并创建一个新的提交F。F是合并开发分支的提交,如果有冲突的话,对冲突进行修改。此方法将为特征分支带来Develp分支的更改,即A和B。现在,您的特征分支上的提交是C,A,D,B,E,F。有3个添加到您的功能分支中的其他提交。
git rebase图示:
rebase变基会移动整个功能分支,就像它从一开始就从开发分支的最新提交分支出来一样。rebase将首先搜索功能分支的基础,然后将其更改为开发分支B上的最新提交,然后根据该基础B将所有提交重新应用到功能分支上。rebase实际上是创建新提交C’,D’,E’,原始提交保持不变。最后,它将要素分支指向的要素从E更改为E’。
这两种方法之间的最大区别在于,merge合并保留了提交的完整历史记录,且按时间顺序排列,而rebase变基使提交变得整洁,仅与分支上的操作相关。当审阅者审阅你的PR时,如果你选择合并,他将看到A,B,C,D,E,F提交,如果您选择rebase,则只会看到C,D,E。Merge具有更高的可追溯性,而Rebase则更整洁且易于审核。
在团队开发中,如果一次性的git push
操作会包含多次commit信息,则此时push前可以用rebase命令合并精简一些提交日志的记录。
7-3 关于git log和git reflog的区别
git log
:用于查看当前分支的提交历史。它会按照提交时间的逆序列出所有提交,并显示每个提交的作者、日期、提交消息等详细信息。可以使用各种选项来过滤和定制输出。git reflog
:git reflog
命令用于查看 HEAD 引用的移动历史,也就是你在本地仓库进行的分支切换、重置等操作,即本地所有分支。它记录了最近的分支操作,包括提交、合并、重置等。每次 HEAD 引用发生变化时,都会有一个新的 reflog 记录添加到 reflog 中。
转载自:https://juejin.cn/post/7264599940537532474