0%

Git log 查看提交历史

在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。

当你在此项目中运行 git log 命令时,可以看到下面的输出:

1
2
3
4
5
6
7
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700

changed the version number

不传入任何参数的默认情况下,git log 会按时间先后顺序列出所有的提交,最近的更新排在最上面。 正如你所看到的,这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。

git log 有许多选项可以帮助你搜寻你所要找的提交, 下面我们会介绍几个最常用的选项。

显示差异

其中一个比较有用的选项是 -p--patch ,它会显示每次提交所引入的差异(按 补丁 的格式输出)。 你也可以限制显示的日志条目数量,例如使用 -2 选项来只显示最近的两次提交:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700

changed the version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
spec = Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = "simplegit"
- s.version = "0.1.0"
+ s.version = "0.1.1"
s.author = "Scott Chacon"
s.email = "schacon@gee-mail.com"
s.summary = "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 16:40:33 2008 -0700

removed unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
end

end
-
-if $0 == __FILE__
- git = SimpleGit.new
- puts git.show
-end

该选项除了显示基本信息之外,还附带了每次提交的变化。 当进行代码审查,或者快速浏览某个搭档的提交所带来的变化的时候,这个参数就非常有用了。 你也可以为 git log 附带一系列的总结性选项。

统计信息

比如你想看到每次提交的简略统计信息,可以使用 --stat 选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700

changed the version number

Rakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 16:40:33 2008 -0700

removed unnecessary test

lib/simplegit.rb | 5 -----
1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 10:31:28 2008 -0700

first commit

README | 6 ++++++
Rakefile | 23 +++++++++++++++++++++++
lib/simplegit.rb | 25 +++++++++++++++++++++++++
3 files changed, 54 insertions(+)

正如你所看到的,--stat 选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结。

展示方式

另一个非常有用的选项是 --pretty。 这个选项可以使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如 oneline 会将每个提交放在一行显示,在浏览大量的提交时非常有用。 另外还有 shortfullfuller 选项,它们展示信息的格式基本一致,但是详尽程度不一:

1
2
3
4
$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

最有意思的是 format ,可以定制记录的显示格式。 这样的输出对后期提取分析格外有用——因为你知道输出的格式不会随着 Git 的更新而发生改变:

1
2
3
4
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit

git log --pretty=format 常用的选项 列出了 format 接受的常用格式占位符的写法及其代表的意义。

选项 说明
%H 提交的完整哈希值
%h 提交的简写哈希值
%T 树的完整哈希值
%t 树的简写哈希值
%P 父提交的完整哈希值
%p 父提交的简写哈希值
%an 作者名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 –date=选项 来定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期(距今多长时间)
%s 提交说明

你一定奇怪 作者提交者 之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。 我们会在 分布式 Git 再详细介绍两者之间的细微差别。

onelineformat 与另一个 log 选项 --graph 结合使用时尤其有用。 这个选项添加了一些 ASCII 字符串来形象地展示你的分支、合并历史:

1
2
3
4
5
6
7
8
9
10
11
$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
* 11d191e Merge branch 'defunkt' into local

这种输出类型会在我们下一章学完分支与合并以后变得更加有趣。

format选项

以上只是简单介绍了一些 git log 命令支持的选项。 git log 的常用选项 列出了我们目前涉及到的和没涉及到的选项,以及它们是如何影响 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(用来定义自己的格式)。
--oneline --pretty=oneline --abbrev-commit 合用的简写。

限制输出长度

除了定制输出格式的选项之外,git log 还有许多非常实用的限制输出长度的选项,也就是只输出一部分的提交。 之前你已经看到过 -2 选项了,它只会显示最近的两条提交, 实际上,你可以使用类似 -<n> 的选项,其中的 n 可以是任何整数,表示仅显示最近的 n 条提交。 不过实践中这个选项不是很常用,因为 Git 默认会将所有的输出传送到分页程序中,所以你一次只会看到一页的内容。

但是,类似 --since--until 这种按照时间作限制的选项很有用。 例如,下面的命令会列出最近两周的所有提交:

1
$ git log --since=2.weeks

该命令可用的格式十分丰富——可以是类似 "2008-01-15" 的具体的某一天,也可以是类似 "2 years 1 day 3 minutes ago" 的相对日期。

还可以过滤出匹配指定条件的提交。 用 --author 选项显示指定作者的提交,用 --grep 选项搜索提交说明中的关键字。

Note 你可以指定多个 --author--grep 搜索条件,这样会只输出匹配 任意 --author 模式和 任意 --grep 模式的提交。然而,如果你添加了 --all-match 选项, 则只会输出匹配 所有 --grep 模式的提交。

另一个非常有用的过滤器是 -S(俗称“pickaxe”选项,取“用鹤嘴锄在土里捡石头”之意), 它接受一个字符串参数,并且只会显示那些添加或删除了该字符串的提交。 假设你想找出添加或删除了对某一个特定函数的引用的提交,可以调用:

1
$ git log -S function_name

最后一个很实用的 git log 选项是路径(path), 如果只关心某些文件或者目录的历史提交,可以在 git log 选项的最后指定它们的路径。 因为是放在最后位置上的选项,所以用两个短划线(–)隔开之前的选项和后面限定的路径名。

限制 git log 输出的选项 中列出了常用的选项

选项 说明
-<n> 仅显示最近的 n 条提交。
--since, --after 仅显示指定时间之后的提交。
--until, --before 仅显示指定时间之前的提交。
--author 仅显示作者匹配指定字符串的提交。
--committer 仅显示提交者匹配指定字符串的提交。
--grep 仅显示提交说明中包含指定字符串的提交。
-S 仅显示添加或删除内容匹配指定字符串的提交。

来看一个实际的例子,如果要在 Git 源码库中查看 Junio Hamano 在 2008 年 10 月其间, 除了合并提交之外的哪一个提交修改了测试文件,可以使用下面的命令:

1
2
3
4
5
6
7
8
$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \
--before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

在近 40000 条提交中,上面的输出仅列出了符合条件的 6 条记录。

隐藏合并提交按照你代码仓库的工作流程,记录中可能有为数不少的合并提交,它们所包含的信息通常并不多。 为了避免显示的合并提交弄乱历史记录,可以为 log 加上 --no-merges 选项。

查看当前分支指向的对象

可以简单地使用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 –decorate。

1
2
3
4
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project

正如你所见,当前 master 和 testing 分支均指向校验和以 f30ab 开头的提交对象。

项目分叉历史

项目分叉历史
你可以简单地使用 git log 命令查看分叉历史。 运行 git log –oneline –decorate –graph –all ,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。

1
2
3
4
5
6
7
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project

由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。 创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符),如此的简单能不快吗?

制作提交简报

现在是时候通知邮件列表里那些好奇你的项目发生了什么的人了。 使用 git shortlog 命令可以快速生成一份包含从上次发布之后项目新增内容的修改日志(changelog)类文档。 它会对你给定范围内的所有提交进行总结;比如,你的上一次发布名称是 v1.0.1,那么下面的命令可以给出上次发布以来所有提交的总结:

1
$ git shortlog --no-merges master --not v1.0.1

包含修改历史

This repo has a lot of files which have been renamed over the years. To see the full history of a file through all of the renames, add --follow to the git log command:

1
$ git log -p --follow README.md

The above log also illustrates a cosmetic problem we have with file history thanks to the svn-to-git conversion in 2020: some svn branch creation events have caused a large number of spurious file deletions in individual file histories

1
git push origin master

origin指定了你要push到哪个remote

master其实是一个“refspec”,正常的“refspec”的形式为”+:”,冒号前表示local branch的名字,冒号后表示remote repository下 branch的名字。

注意,如果你省略了,git就认为你想push到remote repository下和local branch相同名字的branch。

比如

1
$git push origin master:master

(在local repository中找到名字为master的branch,使用它去更新remote repository下名字为master的branch,如果remote repository下不存在名字是master的branch,那么新建一个)

1
$git push origin master

(省略了,等价于“git push origin master:master”)

1
$git push origin master:refs/for/mybranch

(在local repository中找到名字为master的branch,用他去更新remote repository下面名字为mybranch的branch)

1
$git push origin HEAD:refs/for/mybranch

(HEAD指向当前工作的branch,master不一定指向当前工作的branch,所以我觉得用HEAD还比master好些)

1
$git push origin :mybranch

(再origin repository里面查找mybranch,删除它。用一个空的去更新它,就相当于删除了)

LINUX 入门集锦

汇总并总结一下关于LINUX的命令集

CentOS 7 中 Docker 的安装

Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。因此想要安装 docker,只需要运行下面的 yum 命令:

1
# yum install docker

启动 Docker 服务

安装完成后,使用下面的命令来启动 docker 服务,并将其设置为开机启动:

1
2
# service docker start
# chkconfig docker on

or

1
2
3
# systemctl start docker.service
# systemctl enable docker.service

以非root用户的身份来运行Docker

将Docker安装到CentOS上后,你需要将自己添加到docker群组,那样才能以非root用户的身份来运行Docker。为此,使用这个命令:

1
sudo usermod -a -G docker $USER

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

1
# service docker restart

下载官方的 CentOS 镜像到本地

1
# docker pull centos

确认 CentOS 镜像已经被获取

1
2
3
4
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos latest 67591570dd29 2 weeks ago 191.8 MB

运行一个 Docker 容器:

1
2
[root@localhost ~]# docker run -i -t centos /bin/bash
[root@67591570dd29 /]#

搜索基于 Fedora 和 Ubuntu 操作系统的容器。

1
2
# docker search ubuntu
# docker search fedora

docker从主机上复制文件方法

通过docker run命令的-v/–volume参数

假设我们需要将本机的/data 目录分享到Docker的/mnt 目录下, 我们可以通过这样的命令:

1
$ docker run -v /data:/mnt -i -t image-id bash

(假如,在centos或者redhat需要关闭selinux)

CentOS 7 中 Docker 的安装

以前的版本可能为docker-io或者docker,版本比较旧,现在已经更新到docker-ce和docker-ee了。

卸载旧版本

1
$ sudo yum remove docker docker-common docker-selinux container-selinux docker-engine

安装所需包

1
$ sudo yum install yum-utils device-mapper-persistent-data lvm2

配置更新源

1
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

<可选>使能edge与test版本

1
2
$ sudo yum-config-manager --enable docker-ce-edge
$ sudo yum-config-manager --enable docker-ce-test

更新缓存

1
$ sudo yum makecache fast

安装

1
$ sudo yum intall docker-ce

开启docker

1
2
$ sudo systemctl start docker.service
$ sudo systemctl enable docker.service

pgrep/pkill 检索终止当前正在运行的程序

鉴于用man pgrepman pkill的时候出来的同一个释义,所以要一次说两个命令了。

Linux pgreppkill 命令根据名称和其他属性来查找或发送处理的信号。

官方定义为:

pgrep, pkill - look up or signal processes based on name and other attributes

pgrep将查找当前运行的进程中满足条件的并打印到stdout中。

语法

语法如下所示:

1
2
$ pgrep [options] pattern
$ pkill [options] pattern

常用的参数为:

  • -u 选择仅匹配指定有效用户ID进程
  • -I 列出进程名及进程ID
  • -a 列出进程的详细命令行

默认无参数

默认情况下,仅仅列出包含关键词的进程ID。

1
2
3
4
5
6
7
8
9
$ pgrep ssh
3073
3833
4475
5786
5955
11301
13654
...

pkill刚好相反,直接发送终止信号(默认为SIGTERM)给这些进程。

指定用户

可以通过-u来指定用户

1
2
3
4
5
$ pgrep ssh -u username
4475
22084
27695
...

列出进程名

仅仅看到ID是崩溃的,因为不知道具体的进程,可以通过-l来查看进程名

1
2
3
4
5
6
7
8
$ pgrep ssh -l
3073 sshd
3833 ssh-agent
4475 ssh-agent
5786 ssh-agent
5955 sshd
...

更详细的进程信息

或许知道的进程名,还不足以了解具体信息,此时-a选项就爬上用场了。

1
2
3
4
5
6
$ pgrep ssh -a
3073 /usr/sbin/sshd -D
3833 /usr/bin/ssh-agent /etc/X11/xinit/Xclients
5955 sshd: /usr/sbin/sshd -D -f /assets/sshd_config -e [listener] 0 of 100-200 startups
...

pkill 终止当前正在运行的程序

参考 Linux pgrep 命令。

Linux CentOS下查看. 更新. 删除yum安装包

查看CentOS下安装了哪些yum软件包,查看指定包是否有安装,查看已安装包详细说明信息. 更新软件包. 删除软件包等常用操作

  1. 查找指定软件包
1
$ yum search softwate_package_name
  1. 列出所有可安装的软件包
1
$ yum list
  1. 列出所有可更新的软件包
1
$ yum list updates
  1. 列出所有已安装的软件包
1
$ yum list installed
  1. 列出所有已安装但不在Yum Repository软件包资源库内的软件包
1
$ yum list extras
  1. 列出指定的软件包安装信息
1
$ yum list software_package_name
  1. 查看软件包说明信息
1
$ yum info software_package_name
  1. 查看所有软件包说明信息

这个太没有意义了也,就算列出来也是懒得看,实在太多了

1
$ yum info
  1. 更新软件包
1
$ yum update software_package_name
  1. 更新系统
1
$ yum update
  1. 卸载软件包
1
$ yum remove software_package_name

关于yum警告“警告:RPM 数据库已被非 yum 程序修改

这个警告主要因为对一些软件的操作,没有使用yum,比如直接rpm卸载造成的。

至于上面的警告的问题,不必太过惊慌。

主要因为yum的新特征是要成为系统中用户对程序进行管理的接口,这要求yum知道系统中所有的对软件包的操作(yum history)。如果你会用到但不仅只用到yum的话,又不喜欢看到这个警告,你可以去“yum.conf”里把“history_record”设置为“false”。

参考

https://www.cnblogs.com/HermitCarb/p/4759413.html

ubuntu10.4到2016年早已停止了更新支持,ubuntu也不再维护了。官方源以及第三方源包括163,sohu等也不再维护。那是不是意味着这个版本的ubuntu只能放弃使用?

当然不是的!!!

为了解决这个问题,ubuntu提供了old-release的方案,通过命令行更新源如下:

1
sudo gedit /etc/apt/sources.list

打开源列表文件,把里面的地址全删除,然后换上如下的地址,如果你是其他版本的,把lucid替换即可。

1
2
3
4
5
6
7
8
9
10
deb http://old-releases.ubuntu.com/ubuntu lucid main restricted universe multiverse   
deb http://old-releases.ubuntu.com/ubuntu lucid-security main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu lucid-updates main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu lucid-proposed main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu lucid-backports main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu lucid main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu lucid-security main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu lucid-updates main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu lucid-proposed main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu lucid-backports main restricted universe multiverse

然后再运行

1
sudo apt-get update

Enjoy.

for 循环及指定范围语法

1
2
3
4
5
6
7
167> for i in 0...5 { print (i) }
0
1
2
3
4
5

游乐场

对于REPL,测试简单的代码是绰绰有余的,但是对于比较复杂一点的就需要使用Xcode的新特性游乐场了playground。