首页 > 心得分享 > Git 入门使用说明

Git 入门使用说明

Git 入门使用说明

为什么要把参考文档放在前面?

因为总结的并不是很到位,有时间看我瞎逼逼,不如针对性的看一些专业文档。

有哪些基础概念?

  • 仓库: 顾名思义, 就是存放代码的地方, 但和工作区有所区别, 只有进入仓库的代码, 才会被保留、管理

    • 本地仓库: Git 是分布式的, 我们所有的操作都是在 本地仓库, 在本地仓库的所有操作在 push 前, 都 不会影响到 远程仓库
    • 远程仓库: 代码的中转站, 大家的仓库都会通过这里进行汇总, 相互同步, 我们日常只需要从远程仓库 pullpush 这两个操作
  • 工作区: 我们对代码的修改, 都是在工作区上进行的, 如果没有 addcommit 操作, 则修改过的代码 不会进入 仓库
  • 暂存区: 工作区与仓库之间的缓存区域, 工作区的代码进行 add 时, 会先放入暂存区, 当确定要放入仓库时, commit 会将暂存区的代码提交到仓库
  • HEAD: 它指向你最后一次提交的结果, 就是你当前的工作区是 基于什么位置 开始开发的

日常使用 Git,需要那些命令?

其实 Git 的命令行功能非常丰富,但平时可能绝大多数时间只在用其中的几个命令而已。

低频率,但要知道的命令

这些命令基本只会使用那么一两次,但没有他们,你的项目恐怕没法正常开展起来

  • git clone __URL__: 将 远程仓库 复制到 本地仓库
  • git init: 在当前文件夹创建 本地仓库
  • git remote add __NAME__ __URL__: 将 本地仓库远程仓库 关联起来, 你可以同时关联多个远程仓库, 只要 __NAME__ 不同即可, 一般以 origin 为默认值

高频率使用的命令

这些命令将伴随你开发流程的每一个角落, 好在并没有很多

其实 addcommit 确实很适合在 IDE 中进行操作, 可以很细颗粒的以行为单位提交代码, 并且也可以在提交前再次确认 只提交需要提交的代码

  • git status: 查看你 工作区 的当前状态, 里面会有各种情况下建议你进行的操作(这个命令完全 没有任何副作用, 没头绪时, 执行一下也许会有新发现)
  • git add __FILE__ ...: 将 __FILE__工作区 添加到 暂存区, 此时代码并没有真正的被 仓库 所管理, 可以是 文件, 可以是目录, 可以是很多个文件、目录
  • git commit: 如果你已经将本次需要提交的文件 add 到暂存区了, 就可以用这个命令正式提交到 本地仓库, 每次 commit 都会产生一条提交记录 log, 他有一个唯一的 hash id*

    • git commit -m __MESSAGE__: 如果本次修改内容比较少, 则可以使用简易说明提交(如果修改的地方比较多,请 一定写清楚 涉及到的修改), 说明看起来应该是动词+空格+说明, 比如: 调整 手机号的验证规则
  • git pull: 从 远程仓库 获取 当前分支 的最新内容到 本地仓库 (的当前分支), 请注意本地 工作区 是干净的, 不然可能会冲突都头秃
  • git push: 将 本地仓库所有提交 都推送到 远程仓库, 一般都需要先 pull 才可以推送
  • git checkout __BRANCH__: 分支切换, 会将 工作区 的代码切换到 __BRANCH__ 分支上

    • git checkout -b __BRANCH__: 新建分支, 会从 当前分支 分叉一个的新分支 __BRANCH__
    • git branch: 查看 本地仓库 的现有分支, git branch -av 会显示所有仓库(本地仓库、远程仓库) 的所有分支
  • git stash: 储藏代码, 是一个堆栈, 将 工作区 修改了一半的代码临时收起来, 一般在有新任务突然插入时经常这么做

    • git stash pop: 将最后一个 储藏 的代码恢复到工作区, 如果恢复成功则 堆栈 减一, 否则 堆栈 不会改变, 所以不要怕代码会丢失
  • git merge __BRANCH__: 将分支 BRANCH 的代码 合并 到当前分支, 请确认要合并的分支的代码是干净的, 没有你不需要的代码被合并进来

冲突时, 怎么办?

首先, 不要慌!

无论如何, 这种情况下, 你提交到 仓库的代码 是一定不会丢的 (工作区的代码正常情况下也不一定, 但出于各种情况的考虑, 建议 mergepull 代码时, 可以先 addcommitstash 你的代码)

我们先搞清楚, 什么 操作 会导致冲突, 什么 情况 下会冲突, 为什么 会冲突.

什么操作会导致冲突?

一般来说, 下面这些操作可能会出现冲突, 所以在做这些操作前 保持工作区是干净的, 是很好的习惯.

就是: 该提交的提交上去 (add && commit), 该储藏的就储藏起来 (stash).

  • git merge: 合并分支时, 因为很有可能你要合并的分支有和你修改了同一出代码的情况
  • git pull: 从远程仓库拉代码时, 原因同 merge
  • git stash pop: 对, 从 储藏 恢复到 工作区, 也会出现冲突, 不要把你的代码封存太久

什么情况下会冲突?

似乎上面说完了, 就是你要合并的代码和你有同一处修改时, 才会出现这种情况.

为什么会冲突?

抛开分工不明、功能拆分不够细、提交颗粒不够细、提交频率不够频繁之外, 似乎没有其他的原因了.

所以,思考一下?

怎么解决冲突?

如果你在以上操作时出现冲突, 则控制台一般会有这样的输出

自动合并 README.md
冲突(内容):合并冲突于 README.md
自动合并失败,修正冲突然后提交修正的结果。

当你执行 git status 时,会看到这样的提示

位于分支 master
您有尚未合并的路径。
  (解决冲突并运行 "git commit")
  (使用 "git merge --abort" 终止合并)

未合并的路径:
  (使用 "git add <文件>..." 标记解决方案)
    双方修改:   README.md

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")

让我们看下 README.md 里面发生了啥吧

<<<<< HEAD
这是第二次提交的内容
=======
这是第 Test 次提交的内容
>>>>> test

冲突的两段代码会以 ======= 分割, 上面是来自 HEAD 的代码, 下面是来自 test 分支的代码, 选择你要保留的代码,其余的(包括 <<<<< HEAD ======= >>>>> test) 代码删除即可.

当你把所有的冲突就解决之后, 就可以把处理完的结果如平时一样 add commit 将修改提交到仓库.

如果有 IDE ,可能解决冲突会更明了.

怎么减少冲突?

提交的颗粒度尽可能细, 虽然不要每修改一个文件, 或者修改一行代码都要提交, 但解决的每个问题都应该是一个单独的分支, 并及时提交/推送.

日常操作规范

  1. 多建分支, 切换分支应该像翻书一样, 一般有目标不一致的任务时, 都可以新建一个分支
  2. 从尽可能 干净 的分支上创建新分支, 即: 你创建新分支要完成的任务应该是必须依赖这个位置的代码, 而不包含其他地方的代码
  3. 不要将 不干净 的分支上合并到自己的任务分支, 除非你们俩来的地方和要去的地方一定是一致的.

Git-flow 工作流

可能 git 的分支实在是太灵活的, 一不小心分支爆炸, 或者自己都搞不清楚怎么操作, 使用 git-flow 可以 辅助 你管理分支

首先, 我们的分支应该只有这么几个/类主要分支:

  • master / mian: 主分支, 所有的分支都应该是基于它的, 从它出, 但不会合并到它 (只会从 release 分支合并)
  • develop: 开发(自测)分支, 永远不会合并到 master 分支, 开发过程中用于连调、自测
  • test: 测试分支, 当你的 功能稳定 后, 应该通过 Gitlab 的 合并请求 提交到这里, 部署到测试服务器由产品测试进行功能完整性测试
  • release: 预发布分支, 临时的, 只有在即将发布时, 将所有的功能合并于此进行完整的测试, 全部测试通过并实际发布后, 直接合并入 master 分支, 此分支消亡
  • feature/*: 功能分支, 每个功能都应该 至少 有一个功能分支, 功能发布后(合并到 main), 删除此分支
  • bugfix/*: bug 修复分支, 可以以 禅道、issue 等编号或 bug 名称作为分支名称

以上这些分支, 请注意以下要点:

  1. 永远不要从 develop 或 test 切出新分支, 除非你知道你在干什么.
  2. 不要在 mian、develop、test 分支上进行开发和提交.
  3. 不要往 main、test 分支上合并代码(无法推送), 请使用 请求合并 / Merge requests 到 test 分支

一个功能的消亡史

当你接到一个新功能/任务时, 首先将工作区切到 main 分支, 更新 main 的代码(不是必须,但是一个好习惯), 并在此分支上 checkout 出新分支 feature/__NAME__, 继而在新的 feature/__NAME__ 上完成该功能的开发.

git checkout main # 切换到 main 分支
git pull # 更新 main 分支代码到最新
git checkout -b feature/multi-network-port # 签出新的功能分支

请始终在这个分支上提交代码, 请保持这个功能分支上的代码, 一定没有非该功能的新代码.

当这个功能需要测试/连调时, 可将 功能分支 合并到 develop,

git add ...                           # 将 本次修改的文件 添加到 暂存区
git commit                            # 提交修改到 本地仓库
git push                              # 将分支推送到 远程仓库 (非必需, 多人开发同一个功能时需要)
git checkout develop                  # 切换到 开发分支
git pull                              # 更新 开发分支 代码
git merge feature/multi-network-port  # 将功能代码合并
git push                              # 推送到 远程仓库

最后功能写完了, 需要提交到 test 分支进行产品测试, 此时只需要提交你的功能分支并推送到 远程仓库, 然后在 gitlab 的后台使用 合并请求 / Merge requests 发起合并请求.

步骤同 合并到 develop 的前三步骤. 如果期间有 bug 需要修改, 直接在功能分支上继续修改, 然后重复此流程即可.

最后, 我们的版本终于决定要发布了, 此时 可能 会有 release 分支产生, 同样的操作, 只是请求合并到 release 分支而已, 如果没有 release 则可以使用 test 分支作为发布代码亦可.

突然插入新任务时? / 临时修改 bug 时?

好了, 问题来了, 我正在开发功能 A, 写到一半, 突然要插入新任务, 可能是功能 B, 也可能是 bugfix/C, 这个时候我该怎么办?

很简单, 有两种做法:

一、提交代码

将工作区的代码提交到本地仓库, 保持工作区干净 后继续后续的操作

git add ...
git commit

二、储藏代码

你也许有 提交洁癖, 认为无法运行的代码, 或者实验性质的代码不想 “污染” 代码仓库, 那么你可以选择储藏代码(希望你不会放很久)

git stash 命令可以将你工作区的代码直接储藏起来, 当你处理完其他任务时, git stash pop 将会把你 最后一次储藏 的代码恢复到工作区

请尽量在什么位置(分支) stash 的代码,就在什么位置 pop 出来.

储藏区是一个堆栈, 你可以往里面放入多次, 但取出时遵守 后进先出 原则, 如果你要 pop 特定的某次储藏, 可以通过 git stash list 查看历史储藏的 __ID__, 然后使用 git stash pop __ID__ 取出对应的储藏代码

如果在取出 pop 时产生了冲突, 则储藏区的代码不会丢失, 可以手动解决冲突后, 删除储藏区的记录.

然后呢?

工作区干净 后, 从 该 bug 引入 的版本位置(或 main 分支)切出新分支,

在这个分支上进行修改, 一番修改后, 提交到 develop 测试没问题, 向 test (或 main) 发起合并请求

注意, 未发布的代码 在测试中发现的问题, 可以不用bugfix 分支, 直接在原功能分支上直接进行修改即可.

日常管理

每次发布的稳定版, 都应该在发布时及时创建对应版本的 tag 标签 git tag, 后续修改 bug 时将从这些标签上创建 bugfix 分支

上一篇: 换城记

下一篇: Mac 下使用 PHPStorm 在开启 GPG 签名提交 Git 时失败的解决方案

最近回复

标签