git 知识点整理

git 相关知识点整理

文章目录

    • 命令解析
      • git status 查看文件状态
      • git diff 查看文件前后对比
      • git commit 提交记录
      • git rm 删除
      • git stash 备份
      • git log 查看提交历史
      • Git Branch 分支创建(合并分支和分离HEAD)
      • git merge&git rebase 合并分支
      • git reset&git revert 撤销变更
      • git cherry-pick 整理提交记录
      • git fetch 远程下载
      • git push 提交到远程
      • git tag 版本标签
    • 进阶知识
      • 生命周期
      • 忽略内容
      • 分离HEAD
      • 相对引用
      • Git Flow简介

整理来源:

git动画学习

git 知识点问答

git知识点整理

要有分支树的概念,各个分支都是在同一棵树上的

命令解析

中文API解释

git status 查看文件状态

使用 git status 时,实际上可以使用更为方便的指令来达到更为紧凑的格式输出。比如使用 git status -s

$ git status -s

#  M 靠右的 M 表示修改过的文件并且还未被放入暂存区
 M README
 
# MM 靠左的 M 表示该文件被修改后放入了暂存区,靠右的表示修改过的文件并且还未被放入暂存区,所以 Rakefile 文件被修改过后放入了暂存区,但是之后又进行了修改,还未将最后一次修改放入暂存区
MM Rakefile

# A 表示新添加到暂存区的文件
A  lib/git.rb

# M 靠左的 M 表示该文件被修改后放入了暂存区
M  lib/simplegit.rb

# ?? 表示还未被跟踪
?? LICENSE.txt  

# 所以此时暂存区中的文件有 Rakefile, lib/git.rb, lib/simplegit.rb

git diff 查看文件前后对比

git diff 可以说是 git status 的具体版本,git status 只能查看修改了哪些文件,而 git diff 能够具体到该文件的某一部分。通常有以下两个用法

git diff  # 比较当前文件和暂存区文件差异 git diff
git diff  # 比较两次提交之间的差异
git diff   # 在两个分支之间比较
git diff --staged # 比较暂存区和版本库差异
git diff --cached # 比较暂存区和版本库差异

git commit 提交记录

​ Git 仓库中的提交记录保存的是你的目录下所有文件的快照,就像是把整个目录复制,然后再粘贴一样,但比复制粘贴优雅许多!Git 希望提交记录尽可能地轻量,因此在你每次进行提交时,它并不会盲目地复制整个目录,它会将当前版本与仓库中的上一个版本进行对比,并把所有的差异打包到一起作为一个提交记录。

git add . 
$ # 或者~
$ git add newfile.txt
$ git commit -m "the commit message" #
$ git commit -a # 会先把所有已经track的文件的改动`git add`进来,然后提交(有点像svn的一次提交,不用先暂存)。对于没有track的文件,还是需要执行`git add ` 命令。
$ git commit --amend # 增补提交,会使用与当前提交节点相同的父节点进行一次新的提交,旧的提交将会被取消。

​ git commit之前要保证修改文件已执行git add添加进入暂存区。

git rm 删除

要从 Git 中移除某个文件,就必须从已经跟踪的文件清单中删除,然后提交。

删除有两种方式

  • 第一种是简单的从暂存区中删除。但是文件还在被跟踪着。
  • 第二种是直接在未暂存区域中移除文件,表示直接将文件移除版本控制中。不再跟踪
git rm [-f | --force][-n] [-r][--cached] [--ignore-unmatch][--quiet] [--] 

注意:

  • 如果删除文件之前文件修改过并且已经放入了暂存区域,则必须使用强制删除选项-f 才能将其删除。主要是为了防止误删。
  • 当我们想要将文件从 Git 仓库中删除但是却想让他仍在我们的工作区域中时,(即保存在本地磁盘并且不被 Git 跟踪),为了达到这一目的,使用 --cached 选项
  • 如果单纯执行rm,它虽然从磁盘删除,但是git依旧追踪,即远程仓库没有改变】

git stash 备份

​ 当我们已经在一个分支上修改文件后,如果必须要切换到其他分支展开其他的工作,而当前分支的工作还没有完成,此时我们需要使用 $ git stash$ git stash save 命令将当前分支上的工作暂存到栈上,这时你的工作目录就干净了,就可以切换到其他分支工作,等工作完成后,再切换回原来的分支,可以使用 $ git stash apply 将你刚刚的储藏重新应用。

git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。

git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。

git stash pop –index stash@{0}: 恢复编号为0的进度的工作区和暂存区。

git stash apply stash@{1} 以将你指定版本号为stash@{1}的工作取出来

git stash drop[] 删除某一个进度,默认删除最新进度

git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。

git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了

git log 查看提交历史

选项                说明
-p                按补丁格式显示每个更新之间的差异。
--stat            显示每次更新的文件修改统计信息。
--shortstat       只显示 --stat 中最后的行数修改添加移除统计。
--name-only       仅在提交信息后显示已修改的文件清单。
--name-status 显示新增、修改、删除的文件清单。
--abbrev-commit   仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
--relative-date   使用较短的相对时间显示(比如,“2 weeks ago”)。
--graph           显示 ASCII 图形表示的分支合并历史。
--pretty      使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。

常用选项 -p ,用来显示每次提交的内容差异,可以加上 -2 来仅仅显示最近两次提交。现在一般都是用工具或者在网上直接看记录

Git Branch 分支创建(合并分支和分离HEAD)

​ Git 的分支也非常轻量。它们只是简单地指向某个提交纪录 —— 仅此而已。所以许多 Git 爱好者传颂:

早建分支!多用分支!

​ 这是因为即使创建再多分的支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了

# 查看本地分支
git branch

# 查看远程分支
git branch -r

# 创建本地分支(注意新分支创建后不会自动切换为当前分支)
git branch [name]

# 切换分支
git checkout [name]

# 创建新分支并立即切换到新分支
git checkout -b [name]

# 强制删除一个分支
git branch -D [name]

# 移动分支
git branch -f master HEAD^

​ Git 创建新分支的本质就是创建一个可以移动的新的指针。比如创建一个 testing 分支。$ git branch testing 这会在当前所提交的对象上创建一个指针,此时如图

git merge&git rebase 合并分支

git merge 分支1 分支2
git rebase   复制到目标分支 被复制分支

git merge是将两个分支合并会生成一个新的节点,原来的分支没有了

git rebase 不会生成新的节点,是将两个分支融合成一个线性的提交。

  • 解决冲突时。merge操作遇到冲突的时候,当前merge不能继续进行下去。手动修改冲突内容后,add 修改,commit就可以了。而rebase操作的话,会中断rebase,同时会提示去解决冲突。解决冲突后,将修改add后执行git rebase –continue继续操作,或者git rebase –skip忽略冲突。

git reset&git revert 撤销变更

git revert是用一次新的commit来回滚之前的commit,git reset`是直接删除指定的commit。

注意相对位置不同

git reset HEAD^ 撤销前一次commit

git reset HEAD 撤销前一次commit

注意merge不同

  • reset相当于将HEAD指针往前移动,将HEAD指向的位置改变为之前存在的某个版本。(远程老commit还在,push的时候会merge)
  • revert相当于使用一次逆向的commit“中和”之前的提交,创建一个新的状态(push的时候不会在和远程老commit进行Merge)。

在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。

git reset –mixed id: 回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也 不受影响) 
git reset –soft id: 回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响) 
git reset –herd id: 回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换

git cherry-pick 整理提交记录

​ cherry-pick的作用是,将某次或者某几次的提交,在另一个分支上进行重演。(并不想合并而是想拿一些修改状态过来)

git cherry-pick commitid1 commitid2 commitid3 # 多个哈希值空格分开
git cherry-pick commitid1...commitid3# ...表示取两个哈希值区间所有状态(不包含第一个commitid)

看一个在开发中经常会遇到的情况:我正在解决某个特别棘手的 Bug,为了便于调试而在代码中添加了一些调试命令并向控制台打印了一些信息。这些调试和打印语句都在它们各自的提交记录里。最后我终于找到了造成这个 Bug 的根本原因,解决掉以后觉得沾沾自喜!最后就差把 bugFix 分支里的工作合并回 master 分支了。你可以选择通过 fast-forward 快速合并到 master 分支上,但这样的话 master 分支就会包含我这些调试语句了。实际我们只要让 Git 复制解决问题的那一个提交记录就可以了。跟之前我们在“整理提交记录”中学到的一样,我们可以使用git merge两个分支就可以了

git fetch 远程下载

git fetch origin 

git fetch 完成了仅有的但是很重要的两步:

  • 从远程仓库下载本地仓库中缺失的提交记录
  • 更新远程分支指针(如 o/master)

git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态,它不会改变你的本地仓库,也不会改变你的分支.如果不带参数,它将下载所有远程提交记录

既然我们已经知道了如何用 git fetch 获取远程的数据, 现在我们学习如何将这些变化更新到我们的工作当中。

其实有很多方法的 —— 当远程分支中有新的提交时,你可以像合并本地分支那样来合并远程分支。也就是说就是你可以执行以下命令:

  • git cherry-pick o/master
  • git rebase o/master
  • git merge o/master
  • 等等

也就是说你可以选你喜欢的进行合并

git push 提交到远程

git push origin :

git push 提交成功之后本地对应的远程分支也会对应更新

git tag 版本标签

主要就是用于release的时候进行标记。

1.添加标签: git tag -a version -m “note”
注解:git tag 是打标签的命令,-a 是添加标签,其后要跟新标签号,-m 及后面的字符串是对该标签的注释。

2.提交标签到远程仓库 :git push origin -tags
注解:就像git push origin master 把本地修改提交到远程仓库一样,-tags可以把本地的打的标签全部提交到远程仓库。

3.删除标签:git tag -d version
注解:-d 表示删除,后面跟要删除的tag名字

4.删除远程标签:git push origin :refs/tags/version
注解:就像git push origin :branch_1 可以删除远程仓库的分支branch_1一样, 冒号前为空表示删除远程仓库的tag。

5.查看标签:git tag或者git tag -l

git tag -a v0.1.1 master
git push --tags

进阶知识

生命周期

要查看哪些文件处于什么状态,可以用 git status 命令

Git 有四种状态,你的文件可能处于其中之一:

  • Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
  • Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
  • Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
  • Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified

Git 有三种工作区域,你的文件可能处于其中之一:

  • 工作目录 Working Directory :对项目的某个版本独立提取出来的内容,这些从Git仓库的压缩数据库提取出来的文件,放在磁盘上供你使用或修改。
  • 暂存区域 Staging Area :是一个文件保存了下次将提交的文件列表,是待提交文件的暂存区域。一般在Git仓库的目录中,有时也被称为索引。
  • Git仓库:用来保存项目的元数据和对象数据库的地方。是Git中最重要的部分,从其他计算机克隆仓库时拷贝的就是这里的数据

忽略内容

新建一个.gitignore 的文件,列出要忽略的文件模式。
文件 .gitignore 的格式规范如下:

所有空行或者以 # 开头的行都会被 Git 忽略。

可以使用标准的 glob 模式匹配。

匹配模式可以以(/)开头防止递归。

匹配模式可以以(/)结尾指定目录。

要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

\# no .a files  忽略所有.a结尾的文件
*.a

\# but do track lib.a, even though you're ignoring .a files above,被忽略的.a文件中不包括lib.a文件
!lib.a

\# only ignore the TODO file in the current directory, not subdir/TODO
/TODO

\# ignore all files in the build/ directory
build/

\# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt

\# ignore all .pdf files in the doc/ directory
doc/**/*.pdf

分离HEAD

​ HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。

如何判断 Git 当前在哪一个分支?此时就要依靠 HEAD 指针。该指针指向当前所在的本地分支。当HEAD指向一个分支的时候,会变成’分支*’,否则会以HEAD->形式存在。

如图

相对引用

指定某个状态可以用其哈希码,不过哈希码共40位。解决办法有两个:

  • it 对哈希的处理很智能。你只需要提供能够唯一标识提交记录的前几个字符即可。因此我可以仅输入fed2 而不是一长串字符
  • 相对引用(要有一个作为基准,如master或其他分支):
    • 使用 ^向上一层水平移动多个提交记录
    • 使用 ~ 向上移动多个提交记录,如 ~3

Git Flow简介

​ 功能驱动式开发”(Feature-driven development,简称FDD)。它指的是,需求是开发的起点,先有需求再有功能分支(feature branch)或者补丁分支(hotfix branch)。完成开发后,该分支就合并到主分支,然后被删除。

​ 它最主要的特点有两个。首先,项目存在两个长期分支,分别是:主分支master、开发分支develop。其次,项目存在三种短期分支,分别是:功能分支(feature branch)、补丁分支(hotfix branch)、预发分支(release branch),一旦完成开发,它们就会被合并进develop或master,然后被删除。

  • Production分支。也就是我们经常使用的Master分支,这个分支最近发布到生产环境的代码,最近发布的Release, 这个分支只能从其他分支合并,不能在这个分支直接修改。
  • Develop分支。这个分支是我们是我们的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并与其他分支,比如Feature分支。
  • Feature分支。这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回Develop分支进入下一个Release。
  • Release分支。当你需要一个发布一个新Release的时候,我们基于Develop分支创建一个Release分支,完成Release后,我们合并到Master和Develop分支。
  • Hotfix分支。当我们在Production发现新的Bug时候,我们需要创建一个Hotfix, 完成Hotfix后,我们合并回Master和Develop分支,所以Hotfix的改动会进入下一个Release。

你可能感兴趣的:(项目管理)