git使用进阶——工作区和log

Posted 涂宗勋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了git使用进阶——工作区和log相关的知识,希望对你有一定的参考价值。

前言

git的基础操作比较简单,之前我也有过基础操作的记录git操作笔记,但是实际使用时会发现,如果只会最基础的使用,就会有很多需求场景都不能满足,甚至会出错了也不知道为什么,因此在基础使用的基础上,还需要更进一步的理解。

关于工作区、暂存区、版本库和远程仓库的理解

git的版本管理,除了branchtag这些外,实际还有工作区、暂存区、本地版本库、远程版本库等概念(有的地方也把我这里说的本地版本库叫对象区,然后对象区加暂存区一起叫版本库,具体这种概念的理解和差异暂时还无法辨别哪种对,但不影响暂时使用上的理解)。

工作区就是当前可以直接编辑的,比如在idea或者什么工具里编辑文件,保存后就是先保存在工作区。
工作区的改动,通过git add操作可以同步到暂存区。
暂存区的内容,通过git commit提交到本地版本库。(如果不是第一次提交,可以把add和commit合并操作,即git commit -am "message"
本地版本库的内容,通过git push推送到远程版本库。

工作区

例如我有一个文件tzx.txt,在文件所在目录使用git init后,这个文件就会被git管理,在文件所在目录会出现.git目录,里边存放相关信息。
这时候使用git status查看,结果如下:

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        tzx.txt

nothing added to commit but untracked files present (use "git add" to track)

上边内容中,On branch master说明当前所在分支是masterNo commits yet是说有未提交的内容。
Untracked files说明了当前未提交内容的状态,是存在未跟踪的文件,后边的tzx.txt列出了这个文件名。同时,在文件名上边也说了可以进行的git操作git add
最后一句则类似一个总结,意思是没有可以直接commit的内容,但是存在没有被跟踪的文件。
结合上边的理解,其实就是说tzx.txt这个文件现在仅仅存在于工作区,可以使用git add增加到暂存区中。

暂存区

那么使用git add tzx.txt操作后再使用git status查看,结果如下:

On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   tzx.txt

那么这里,主要是后边一段,Changes to be committed意思是存在需要提交的更改,new file: tzx.txt意思是有新的文件tzx.txt可以被commit
use "git rm --cached <file>..." to unstage这一句,则是指除了commit之外还可以进行的操作,实际就是从暂存区回到工作区。

本地版本库(对象区)

接下来在进行git commit操作,例如git commit -m "git init",再使用git status查看结果如下:

On branch master
nothing to commit, working tree clean

nothing to commit, working tree clean,当前没有可以再被提交的内容,即暂存区的内容也提交到了本地版本库,当前状态是工作区、暂存区、本地版本库的信息一致。

远程版本库

至于从本地版本库推送到远程版本库,在开篇链接的git基础操作中已有记录。

关于git log

git log

对于上边的commit,使用git log查看日志,结果如下:

commit e84e73795add11ea1c1cc4bce9bf0788bed4981e (HEAD -> master)
Author: tuzongxun <1160569243@qq.com>
Date:   Wed Sep 14 20:29:46 2021 +0800

    git init

为了更好的演示一些效果,这里多加几个提交,例如:

Author: tuzongxun <1160569243@qq.com>
Date:   Wed Sep 14 20:52:01 2021 +0800

    git2

commit 891480792069a8168d8fe59032cfbff4156804a0
Author: tuzongxun <1160569243@qq.com>
Date:   Wed Sep 14 20:51:30 2021 +0800

    git1

commit e84e73795add11ea1c1cc4bce9bf0788bed4981e
Author: tuzongxun <1160569243@qq.com>
Date:   Wed Sep 14 20:29:46 2021 +0800

    git init

上边的内容,显示了每次commit的id,或者说sha1值,sha1是一种加密算法,这里实际就是为了生成分布式的唯一id。
除了id,还展示了提交人和时间。

prettyabbrev-commit

上边的信息很多,但是有时候可能并不需要这么多的信息,就可以指定一些参数来简化输出,例如执行git log --pretty=oneline --abbrev-commit,输出如下:

d5238e6 (HEAD -> master) git2
8914807 git1
e84e737 git init

上边信息就只展示了id值的前几位和提交时的注释等信息,比没有参数时简洁很多。

git log --graphmerge --no-ff

除了简化输出,有时候可能需要更直观的展示分支之间的关系,也会常用graph,例如git log --graph输出如下:

* commit d5238e64666acdec89120603a58238a5ed46a2a7 (HEAD -> master)
| Author: tuzongxun <1160569243@qq.com>
| Date:   Wed Sep 14 20:52:01 2021 +0800
|
|     git2
|
* commit 891480792069a8168d8fe59032cfbff4156804a0
| Author: tuzongxun <1160569243@qq.com>
| Date:   Wed Sep 14 20:51:30 2021 +0800
|
|     git1
|
* commit e84e73795add11ea1c1cc4bce9bf0788bed4981e
  Author: tuzongxun <1160569243@qq.com>
  Date:   Wed Sep 14 20:29:46 2021 +0800

      git init

这里会看到在git log的基础上,最左边增加了一条线,由于我这里目前只有master分支,所以可能看不出效果,那么,这里再创建一个新的分支dev,然后修改代码后合并到master,步骤如下:

  1. 在master分支使用git checkout -b dev创建并切换到dev分支;
  2. 修改内容后,git commit -am “add dev branch”提交修改;
  3. 使用git checkout master切换到master;
  4. 使用git merge --no-ff dev合并dev到master。(–no-ff见下文)

然后查看日志,为了信息更简洁,这里采用git log --graph --pretty=oneline --abbrev-commit,输出如下:

*   6209d36 (HEAD -> master) Merge branch 'dev' no fast forward
|\\
| * 3e6801b (dev) add dev branch
|/
* d5238e6 git2
* 8914807 git1
* e84e737 git init

从上边的内容中可以很明显的看到,在master上先有三个提交,分别是e84e7378914807d5238e6
然后在d5238e6这个点创建了dev分支,然后在dev上有了新的提交3e6801b
然后在3e6801b之后,dev合并到了master上,并且有了一个新的id值6209d36

那么这里其实需要着重说一下merge--no-ff,为了进一步说明,这里回到dev分支修改文件内容后再做一次提交,然后再合并到master,不同的是,这一次不要--no-ff参数,步骤如下:

  1. 使用git checkout dev切换回dev
  2. 修改tzx.txt文件后,使用git commit -am "update dev content"提交;
  3. 使用git checkout master切换回master;
  4. 使用git merge dev合并devmaster

然后查看日志,结果如下:

*   d553853 (HEAD -> master) ierge branch 'dev'
|\\
| * ca381cd (dev) update dev content
* | 6209d36 Merge branch 'dev' no fast forward
|\\|
| * 3e6801b add dev branch
|/
* d5238e6 git2
* 8914807 git1
* e84e737 git init

上边的内容中,也可以看到,在6209d36之后,dev分支上有了一个新的提交ca381cd,然后把dev又合并到了master
但是这里依然不能说明--no-ff的作用,因此我这里回到master再创建一个新的分支sit,然后修改提交后,再把sit合并到master,不使用--no-ff参数,步骤如下:

  1. 在master上使用git checkout -b sit创建并切换到sit分支;
  2. 修改tzx.txt的内容后,使用git commit -am "add sit branch"提交;
  3. 使用git checkout master切换回master
  4. 使用git merge sit合并sitmaster.

然后再查看日志,结果如下:

* ef5b082 (HEAD -> master, sit) add sit branch
*   d553853 ierge branch 'dev'
|\\
| * ca381cd (dev) update dev content
* | 6209d36 Merge branch 'dev' no fast forward
|\\|
| * 3e6801b add dev branch
|/
* d5238e6 git2
* 8914807 git1
* e84e737 git init

这个时候就会看到,ef5b082这一次的提交,明明是在sit分支上提交的,但是现在却显示在master上。
同时,之前dev合并到master时,会生成一个新的id,而这里没有生成。
那么这里其实一定程度上展示了--no-ff的作用,也就是当我们使用过--no-ff,后续相应分支的合并后就会在合并后的分支保留被合并分支相关的信息,同时会在合并后有一个新的记录。
而如果没有用过这个参数,合并后就不会在合并后的分支中保留原来的分支信息,并且合并后也不会生成新的id记录。
这里的ff实际上是fast forward的意思,翻译过来就是快进。
也就是说,git merge默认情况下是fast forward的,不会在合并后的分支中保留被合并的分支信息,如果要保留,就需要使用或者使用过--no-ff参数。

以上是关于git使用进阶——工作区和log的主要内容,如果未能解决你的问题,请参考以下文章

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

GitHub 系列之「Git 进阶」

转载从0开始学习 GitHub 系列之「Git 进阶」

git 进阶命令

git 进阶命令

git使用进阶——版本穿梭reset三种模式理解