Git

Git基本概念&操作

Git基本概念&操作

Posted by limantang on December 12, 2019

Git基本概念&操作

git中的三种状态

  • 已提交committed 数据已经存储到本地的数据库(本机电脑)
  • 已修改modified 修改了文件但是还没有保存到数据库
  • 已暂存staged 对已修改的文件当前版本做了标记, 这个文件包含在下次提交的快照当中

git三个工作区域

  • git仓库 一般是指远端的git仓库 保存着项目的元数据和对象数据库
  • 工作目录 对于项目的某个版本单独拉取出的内容
  • 暂存区域 暂存区域是一个文件,保存了下次将提交(commit)的文件列表信息

git基本工作流程

  • 在工作目录修改文件
  • 暂存文件, 将文件的快照放入暂存区
  • 提交更新, 找到暂存区的文件, 将快照永久的存储到git仓库目录
  1. 如果git目录中保存着特定版本的文件, 就属于提交状态
  2. 如果做了修改并且放入暂存区域就属于已暂存状态
  3. 自从上次提取后做了修改但是没有放入暂存区, 就属于已修改

查看当前文件状态

使用git status

可能会存在以下四种状态

  • Untracked 文件未跟踪
  • Unmodified 文件未更改
  • Modified 文件已更改
  • Staged 文件已暂存

git add

  • 一个新添加的文件查看文件状态会显示未跟踪状态, 要使用git add 添加新的跟踪, 此时这个文件状态就是已跟踪, 已暂存
  • 修改一个已跟踪的文件, 查看状态会显示未暂存状态, 需要使用git add添加到暂存区
  • git add 是一个多功能命令, 如果文件未跟踪, 有添加跟踪的能力, 如果文件未暂存有添加到暂存区的能力, 如果文件有冲突可以标记为冲突已解决

忽略文件

使用.gitignore来记录需要忽略的文件或者文件夹

git diff

这个命令可以查看未暂存, 已修改文件更新了哪些部分

提交(commit)更新

git commit -m "本次commit的描述信息” 提交是将暂存区的文件committed 已修改但是未在暂存区的文件是不会committed 可以使用git commit -a -m “描述信息”来将已跟踪但是未暂存的文件连同暂存区的文件一同committed, 从而跳过了git add 这一步

移除文件

从git仓库中删除, 但是继续保存在工作目录当中, 也就是说想继续保存在磁盘中, 但是不想要git继续跟踪管理, 可以这样操作 git rm —cached 文件名

查看提交记录

git log

撤销操作

  1. 如果遇到提交信息写错, 或者漏掉了几个文件没有提交, 可以使用 git commit —-amend命令来重新填写commit信息, 这一次将会代替上次的提交, 而不是产生两次提交
  2. 如果不小心将某个文件添加到暂存或者不想将某个文件添加到暂存可以使用git reset HEAD 文件名
  3. 如果撤销对一个文件的修改 可以使用git checkout --文件名

Git分支

在了解分支之前先看一下git是如何存储数据的

假设有一个初始化的新的项目 使用git add .添加三个新的文件到暂存区 然后使用git commit -m “first commit”来提交 在进行提交操作时, git根据文件目录和文件计算出校验和, 然后创建一个提交对象, 树对象, blob对象 现在git仓库中就存在了五个对象 提交对象(包含提交信息, 对应的树对象信息等), 树对象(包含对象的文件目录和文件信息), 三个blob对象(文件快照) 也可以这样理解

  • 提交对象: 存储着本次提交信息和树对象信息
  • 树对象: 存储着目录信息, 和本次提交关联的文件内容
  • blob对象: 本次提交的具体文件内容信息

如果此时再次修改再次提交, 就会产生新的提交对象和树对象, 每次的提交对象和响应产生的树对象产生关联

第二次产生的提交对象会包含一个指向上一次(第一次)的指针(父对象) 第三次第四次也是如此…

其实git分支只是一个指向提交对象的指针

分支

假如目前的分支是master, git的默认分其实也是master 对此修改提交之后(每次提交之后master都会自动指向新生成的提交对象), master就是指向最后一次的提交对象

创建分支

使用git branch 新的分支名来基于当前分支来创建一个新的分支

那么git是如果判断当前处于哪个分支呢

其实还有一个HEAD特殊指针一直指向的是当前分支, 使用git branch不会切换分支, 也就是说当前还是处于master分支, 也就是说HEAD执行指向的还是master

切换分支

git checkout 分支名这个命令可以切换分支, 当切换分支之后(假设分支名是test), HEAD指针就指向test, 也就是说当前的分支就是test分支

git pull & git fetch

当拉取远端分支代码时可以使用git pull 或者 git fetch 两者有什么区别呢 可以使用git branch -a 来查看所有的远端分支和本地分支 如果本地的分支已经推送到远端仓库, 那么远端分支和本地分支会相互对应

比如本地的master分支会有一个对应的remotes/origin/master分支对应

git fetch就是在拉取最新的远端分支到本地, 假设只有一个master分支, 也就是在更新remotes/origin/master

加入此时处于master分支, 这时在进行分支合并 git merge origin/master 就成功了的更新的本地的分支

git pull就相当于上面的git fetch git merge origin/master

Git撤销操作

git reset

场景一: 从暂存中移除

  • 创建了一个文件 touch a.md
  • git add a.md 加入暂存
  • 从暂存移除 git reset
  • 使用git rm –cached a.md也可以达到同样的效果

场景二: 取消提交

  • touch a.md
  • git commit -a -m ”commit”
  • git reset –soft HEAD~1 从提交状态退回到暂存区, 文件本身不变(commit记录也不存在了)

  • git reset –mixed HEAD~1 从提交状态退回到未跟踪状态, 也就是提交==>暂存==>未提交(commit记录也不存在了)

  • git reset –hard HEAD~1 从提交提交状态退回到未跟踪状态, 然后将文件删除(commit记录也不存在了)

git revert

git revert可以回退到某次commit的代码,但是会增加一份新的commit记录, git revert还会保留以前的commit历史记录, git revert更安全

git checkout

可以切换到某次commit, 但是切换之后只可以看, 不可以写