git的理解与使用

本地的git

git除了最经典的add commit push用来做版本管理,其实他的分支管理也非常强大

可以说你学好了分支管理,就可以完成团队的配合协作了

git仓库

我们可以使用git init来初始化一个git仓库,只要能看见.git文件夹,就代表这是一个git仓库了

git分区

git一共有三个分区,工作区、暂存区、版本库

工作区

.git文件夹在相同目录即为工作区,也就是我们写代码的地方

暂存区与版本库

这两个分区实际上是存在.git文件夹里的

当我们使用add之后,代码就会被存储在暂存区,只有commit之后,也就是提交代码,整个代码才会被放入版本库,也就是上图的master文件夹中

我们也可以偷看一下.git文件夹,需要注意的是,我们绝不能更改.git文件夹的任何内容

在整个git目录中,我们不需要全部搞明白,只需要抓住几个核心文件即可

  • objects:这是一个对象目录,存储的是git对象,Git进行版本管理的核心不是将文件全部备份,而是只记录修改的部分,当工作区代码修改后,会将修改的内容写入obj库中的一个新git对象中,因此暂存区和版本库存的不是数据本身,而是git对象的索引,以便快速定位与修改
  • index:暂存区,add之后就会更新这里的内容,我还没有add所以并没有这个文件夹
  • /refs/heads/master:这是当前master分支(版本库)的最新一次提交的id索引,在每一次提交的内容中都会保存上一次提交的索引id,因此整个版本库就像一个链表一样
  • HEAD:这是一个指针,用于指向当前我们处于版本库的哪一个位置,也就是在链表的哪一个节点

git 本地常用命令

add commit这里就不说了,分别就是将文件保存到暂存区和提交到版本库

  • 查看工作区与暂存区代码差异:git diff [file]
  • 查看版本库与工作区代码差异:git diff head -- [file]
  • 查看提交记录:git log

commit后面那一串代码是提交的ID,每一次的提交ID都是独一无二的,确保我们可以进行版本回退

版本回退

版本回退是比较复杂的,核心是使用git reset [--soft | --mixed | --hard] [HEAD] 实现的

我们核心理解的是,版本回退指的是将版本库中的内容进行回退,工作区和暂存区是否回退则由参数决定

  • --mixed 是默认选项,会将暂存区的内容回退,工作区不变
  • --soft 是工作区和暂存区都不回退
  • --hard 是暂存区和工作区都回退,当工作区有未保存备份提交的代码时不要使用这个选项!否则工作区代码无法找回!
  • HEAD选项是标识当前版本 HEAD^ 标识上一个版本 HEAD^^ 标识上两个版本,可以依次类推,也可以直接写上面的提交ID,回退到指定版本

如果不小心全部回退到目标版本之前的某个版本了,这时git log是无法找到目标版本的提交ID了,需要使用git reflog,查看所有提交的命令,再利用ID回退到目标版本即可

删除文件

git rm 删除工作区和暂存区的文件

撤销修改
  1. 撤销工作区的修改:git checkout -- [file] 将工作区文件恢复到最近一次add或commit的状态
  2. 撤销工作区和暂存区的代码:使用git reset --mixed [HEAD],会将暂存区和版本库的代码进行回退,工作区不变,变为第一种情况
  3. 全部回退:git reset --hard [HEAD],前提是不能push,因为推送到远端仓库后再回退其实就意义不大了,本身就是为了避免不影响远端仓库的

分支管理

master分支或者main分支为主分支,一般大型项目都不在主分支上,分支就像是分身一样,写不同部分的代码,最后合并就是完整的项目,因此我们也可以进行分支的创建、切换、合并

比如我们现在创建一个dev分支,我们可以把这个时间线画出来

创建分支git branch [name],查看分支git branch

星号就标识我们当前所处的分支

使用git checkout [name]可以切换分支

我们可以在dev分支中创建文件,编写代码

写好后我们切换到master分支,会发现工作区的文件和代码并没有改变

在dev分支合并之前,master主分支都不会收到影响

这是因为dev分支的新提交对于master分支来说是完全不可见的

那要进行部署上线,就需要合并分支,可以利用git merge [name]进行分支合并

需要注意的是,这个name指的是需要将name分支合并到当前所在分支

例如当前是master分支,使用git merge dev是将dev分支合并到master分支

合并分支之后分支并没有删除,仍然可以继续开发,因此合并也可以用来同步各个分支的代码

如果某个分支没有用了,就可以使用git branch -d [name]删除指定分支

如果两个分支是两个团队在维护,并且他们都对同一个文件进行修改了,合并会发现有冲突,就像下面这样

这种情况下git会提示我们哪些文件有冲突,我们需要手动修改保留代码,然后再进行一次add和commit,就可以解决冲突了

Fast forword模式

这是一种分支合并的模式,在这种模式下,删除分支后查看分支历史时,就无法查看到以前的分支信息了,我们无法直到这个最新提交是merge来的还是commit来的

但是我们在解决冲突之后再commit一次,这样就不是fast forword模式了,就能看出分支信息了

git也可以强制禁用 fast forword git merge -no-ff -m "合并" [name]

这样就会自动生成新的commit,就能看到分支信息了

这里需要边操作边理解画图,才能更好理解

分支管理策略

一般来说master分支是最稳定的,也就是服务部署的分支,然后是dev开发分支,开发分支可以再继续细分到具体的某个人,如果开发只有你一个人来包揽也是可以的,类似的还有feature分支

如何管理和实践还是因人而异了

master分支遇见BUG怎么办

master分支突然遇到bug,有两种解决的思路

第一种是直接在master上开一个新的bug分支,然后再改bug,改好之后直接合并,最后删除bug分支

第二种是需要在dev分支上修,但是dev分支上还有未完成的工作,我们就可以使用git stash将当前工作区文件信息进行存储,然后修bug,修好之后给push回去,之后再使用git stash list可以查看内容,用git stash pop恢复即可

远端的git

其实远端的git是用于合作用到的更多,例如github,gitee都是代码托管平台,相当于免费给了一个远程的代码存储服务器

我们在push和pull的时候其实就是和远端的git仓库进行互动,将本地的所有git信息发到远端去了

但是在多人协作时,还是要优先使用pull,将其他人的代码拉下来,再进行push,要提前在本地解决好冲突才行

git标签

试想一下这样的场景, 公司在团队协作开发项目时, commit提交了上万次, 但是此时你想要回滚到某个特定的commit版本, 你怎么应对? 难道一个一个的去找吗? 难受, 实在是难受

理解标签

标签tag可以理解为对某次commit的一个标识, 相当于为此次commit取别名, 例如在项目发布某个版本时, 可以给最近一次commit打上v1.0的标签,这样下次需要回滚到1.0版本的提交时, 就不需要查看log了, 只需要查看tag标签即可定位

常用指令如下

  • 创建标签:git tag [name],如: git tag v1.0
    • 此标签默认打在最新一次提交的commit id上
  • 查看所有标签:git tag
  • 给标签标注信息: git tag -a [name] -m "信息"
  • 查看标签信息:git show [标签名]
  • 删除标签:git tag -d [标签名]
  • 推送标签至远端服务器:git push origin v1.0
  • 推送所有标签:git push origin --tags
相关推荐
Yeats_Liao11 小时前
Git 如何将旧仓库迁移新仓库中,但不显示旧的提交记录
git
五月仲夏14 小时前
git基础指令大全
大数据·git·elasticsearch
节省钱14 小时前
【Git】如何在 Git 提交后补充 Change-Id
服务器·git·gitee·gitlab·github·gitcode
想一个不重名的名字14 小时前
Git知识分享
git
dujunqiu1 天前
gitlab处理空文件夹的提交或空文件夹提交失败
git·gitlab·github
Hello Dam1 天前
Git 小白入门教程
git
Junmay661 天前
Git常用操作指令
git·github
这猪好帅2 天前
【Git版本控制器--3】Git的远程操作
git
smile_life_2 天前
git和idea重新安装后提交异常
java·git·intellij-idea