IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> Git版本控制管理——提交 -> 正文阅读

[开发工具]Git版本控制管理——提交

在Git中,提交是用来记录版本库的变更的。

当提交时,Git会记录索引的快照并将快照放进对象库,该快照不包含该索引中任何文件或记录中的副本。Git会将当前索引的状态与之前的快照做一个比较,并派生出一个受影响的文件和目录列表,并会为任何有变化的文件创建新blob对象,对有变化的目录创建新的树对象,对于未改动的文件和目录则会沿用之前的blob与树对象。

提交的快照是串联到一起的,每张新的快照指向其前驱,随着时间的推移,一系列变更就表示为一系列提交。

版本库中的变更和提交时一一对应的关系,提交则是将变更引入版本库的唯一方法,任何版本库中的变更都必须由一个提交引入。

原子变更集

每个Git提交都代表一个相对于之前状态的单个原子变更集合。即一个提交中的改动,无论包含多少文件,多少修改内容,要么全部应用,要么全部拒绝。

这点和数据库操作是一致的,不能十行修改因为某个不知名的原因只成功提价了九行,那如何定位未提交的一行很显然也是一个问题。

而在底层对象模型方面,原子性也是有意义的:一张提交快照就代表所有文件和目录的变更,其表示了一棵树的状态,而两张提交快照之间的变更集就代表一个完整的树到树的转换。

识别提交

在Git中,可以通过显式或隐式引用来指代每一个提交。如某次提交的散列值是显式提交,而始终指向最新提交的HEAD则是隐式提交。

同时Git提供了不同的命名机制来提交命名,

绝对提交名

在Git中,最严格的识别提交方式肯定是散列值,毕竟Git中的对象都是通过散列值识别的。

$ git log -1 --pretty=oneline HEAD
9f1d1da871fe53fcaa5bdaa8417b47ab7b1b740f (HEAD -> master) commit file

$ git log -1 --pretty=oneline 9f1d1da871fe53fcaa5bdaa8417b47ab7b1b740f
9f1d1da871fe53fcaa5bdaa8417b47ab7b1b740f (HEAD -> master) commit file

比如上面的命令会识别出散列值对应的提交,并打印。

引用和符号引用

引用(ref)是一个散列值,指向Git对象库中的对象。虽然一个引用可以指向任何Git对象,但是其通常指向提交对象。符号引用(symbolic reference),或称为symref,间接指向Git对象。

本地特性分支名称,远程跟踪分支名称和标签名都是引用。

每一个符号引用都有一个以ref/开始的明确全称,并且都分层存储在版本库的.git/refs/目录中。目录中基本有三种不同的命名空间代表不同的引用:

  • refs/heads/ref代表本地分支
  • refs/remotes/ref代表远程跟踪分支
  • refs/tags/ref代表标签

比如当前版本库的引用目录为:

$ find .git/refs/
.git/refs/
.git/refs/heads
.git/refs/heads/master
.git/refs/tags

同时Git会自动维护几个用于特定目的的特殊符号引用,这些引用可以在使用提交的任何地方使用。

  • HEAD:HEAD始终指向当前分支的最近提交,当切换分支时,HEAD会更新为指向新分支的最近提交。
  • ORIG_HEAD:某些操作,如merge或reset,会把调整为新值之前的先前版本的HEAD记录到ORIG_HEAD中。可以使用ORIG_HEAD来恢复或回滚到之前的状态或者做一个比较。
  • FETCH_HEAD:当时用远程库时,git getch命令将所有抓取分支的头记录到.git/FETCH_HEAD中。FETCH_HEAD是最近抓取的分支的HEAD的缩写,并且仅在刚刚抓取操作之后才有效。
  • MERGE_HEAD:当一个合并操作正在进行时,其它分支的头暂时记录在MERGE_HEAD中。换言之,MERGE_HEAD是正在合并进HEAD的提交。

所有的这些符号引用都可以使用底层命令git symbolic-ref进行管理。

相对提交名

Git还提供一种机制来确定相对于另一个引用的提交,通常是分支的头。

开发中关于提交可能会出现master、master^、master~2之类的符号,这就是相对提交名。

除了第一个根提交外,所有的提交都来自至少一个比其更早的提交,即父提交。而若一个提交存在多个父提交,那么其必定是由合并操作产生的。

在同一代提交中,插入符号^是用来选择不同的父提交的。比如给定提交A,A^1表示其第一个父提交,A^2表示其第二个父提交。而波浪线~用于返回父提交之前并选择上一代提交,比如给定提交A,A~1表示其第一个父提交,A~2表示其第一个父提交的第一个父提交。

同时还存在一些特殊写法,比如A~1、A^1、A~、A^含义相同,都是A第一个父提交,A^^、A^1^1含义也相同,实际使用需要灵活运用。

这里以git的源码为例,看下其提交的历史:

$ git show-branch master --more=35 | tail -10
fatal: bad sha1 reference --more=35

$ git show-branch --more=35 | tail -10
[master~9^2~3] t2107: test 'git update-index --verbose'
[master~7^2~6] Git 2.37-rc0
[master~10] Merge branch 'jk/perf-lib-test-titles'
[master~10^2] perf-lib: fix missing test titles in output
[master~10^2^] t/perf: add iteration setup mechanism to perf-lib
[master~11] builtin/rebase: remove a redundant space in l10n string
[master~12] Fixes and updates post -rc0
[master~13] Merge branch 'fs/ssh-default-key-command-doc'
[master~13^2] gpg docs: explain better use of ssh.defaultKeyCommand
[master~14] Merge branch 'po/rebase-preserve-merges'

其中的一次提交为:

$ git rev-parse master~13^2
ce18a30bb78720d90df42b9d9ee6b8b7dd33d7e6

$ git cat-file -p ce18a30bb78720d90df42b9d9ee6b8b7dd33d7e6
tree ff62097391dd860007845ec05624eb1decfc740e
parent dc8c8deaa6b5847733bd7df011a4c7b7d1a64e0a
author Fabian Stelzer <fs@gigacodes.de> 1654701877 +0200
committer Junio C Hamano <gitster@pobox.com> 1654731220 -0700

gpg docs: explain better use of ssh.defaultKeyCommand

Using `ssh-add -L` for gpg.ssh.defaultKeyCommand is not a good
recommendation. It might switch keys depending on the order of known
keys and it only supports ssh-* and no ecdsa or other keys.
Clarify that we expect a literal key prefixed by `key::`, give valid
example use cases and refer to `user.signingKey` as the preferred
option.

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

从中可以看出,该次提交对应的散列值正是对应的本次提交,这样说起来可能有点绕,但是相对提交名确实是有效的。

而Git中的git rev-parse命令会将任何形式的提交名,包括标签,相对名,简写或绝对名称都转换为对象库中的散列值。

提交历史记录

查看旧提交

显式提交历史记录的命令主要是git log,该命令还存在很多参数。

不过首先git log的形式和git log HEAD的作用一样,输出每一个可以从HEAD找到的历史记录中的提交日志信息。变更从HEAD提交开始进行回溯,并且Git是基于其内部的提交图进行回溯的,跟提交时间并不完全一致。

而如果在git log命令中显式提供了一个提交名,那么该日志将从该提交开始回溯。

$ git log
commit 5b71c59bc3b9365075e2a175aa7b6f2b0c84ce44 (HEAD -> master, tag: v2.37.0-rc1, origin/master, origin/main, origin/HEAD)
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 17 17:15:13 2022 -0700

    Git 2.37-rc1

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

commit 694c0cc0fb531b17750ac6e81920054f193f8eb8
Merge: b4eda05d58 6b11e3d52e
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 17 17:12:31 2022 -0700

    Merge branch 'cb/path-owner-check-with-sudo-plus'

    "sudo git foo" used to consider a repository owned by the original
    user a safe one to access; it now also considers a repository owned
    by root a safe one, too (after all, if an attacker can craft a
    malicious repository owned by root, the box is 0wned already).

    * cb/path-owner-check-with-sudo-plus:
      git-compat-util: allow root to access both SUDO_UID and root owned

commit 6b11e3d52e919cce91011f4f9025e6f4b61375f2
Author: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Date:   Fri Jun 17 13:23:38 2022 -0700

    git-compat-util: allow root to access both SUDO_UID and root owned

    Previous changes introduced a regression which will prevent root for
    accessing repositories owned by thyself if using sudo because SUDO_UID
    takes precedence.

    Loosen that restriction by allowing root to access repositories owned
    by both uid by default and without having to add a safe.directory
    exception.

    A previous workaround that was documented in the tests is no longer
    needed so it has been removed together with its specially crafted
    prerequisite.

    Helped-by: Johanness Schindelin <Johannes.Schindelin@gmx.de>
    Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

commit b4eda05d58ca3e4808d3d86ab5826c77995a06f7
Author: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Date:   Fri Jun 17 18:03:09 2022 +0800

    i18n: fix mismatched camelCase config variables

    Some config variables are combinations of multiple words, and we
    typically write them in camelCase forms in manpage and translatable
    strings. It's not easy to find mismatches for these camelCase config
    variables during code reviews, but occasionally they are identified
    during localization translations.

    To check for mismatched config variables, I introduced a new feature
    in the helper program for localization[^1]. The following mismatched
    config variables have been identified by running the helper program,
    such as "git-po-helper check-pot".

    Lowercase in manpage should use camelCase:

     * Documentation/config/http.txt: http.pinnedpubkey

    Lowercase in translable strings should use camelCase:

     * builtin/fast-import.c:  pack.indexversion
     * builtin/gc.c:           gc.logexpiry
     * builtin/index-pack.c:   pack.indexversion
     * builtin/pack-objects.c: pack.indexversion
     * builtin/repack.c:       pack.writebitmaps
     * commit.c:               i18n.commitencoding
     * gpg-interface.c:        user.signingkey
     * http.c:                 http.postbuffer
     * submodule-config.c:     submodule.fetchjobs

    Mismatched camelCases, choose the former:

     * Documentation/config/transfer.txt: transfer.credentialsInUrl
       remote.c:                          transfer.credentialsInURL

    [^1]: https://github.com/git-l10n/git-po-helper

    Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

commit b81b98f818fdacdc472f2afed2ae67d9d0893fe2
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 17 10:33:42 2022 -0700

    Another batch of fixes before -rc1

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

commit aa11b94ef87050af9e4e0aab64f1ab89636c5be4
Merge: 7f5a382aa5 f8535596aa
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 17 10:33:32 2022 -0700

    Merge branch 'jk/bug-fl-va-list-fix'


$ git log 6b11e3d52e919cce91011f4f9025e6f4b61375f2
commit 6b11e3d52e919cce91011f4f9025e6f4b61375f2
Author: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Date:   Fri Jun 17 13:23:38 2022 -0700

    git-compat-util: allow root to access both SUDO_UID and root owned

    Previous changes introduced a regression which will prevent root for
    accessing repositories owned by thyself if using sudo because SUDO_UID
    takes precedence.

    Loosen that restriction by allowing root to access repositories owned
    by both uid by default and without having to add a safe.directory
    exception.

    A previous workaround that was documented in the tests is no longer
    needed so it has been removed together with its specially crafted
    prerequisite.

    Helped-by: Johanness Schindelin <Johannes.Schindelin@gmx.de>
    Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

commit b9063afda17a2aa6310423c9f7b776c41f753091
Author: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Date:   Thu May 12 18:00:19 2022 -0700

    t0034: add negative tests and allow git init to mostly work under sudo

    Add a support library that provides one function that can be used
    to run a "scriplet" of commands through sudo and that helps invoking
    sudo in the slightly awkward way that is required to ensure it doesn't
    block the call (if shell was allowed as tested in the prerequisite)
    and it doesn't run the command through a different shell than the one
    we intended.

    Add additional negative tests as suggested by Junio and that use a
    new workspace that is owned by root.

    Document a regression that was introduced by previous commits where
    root won't be able anymore to access directories they own unless
    SUDO_UID is removed from their environment.

    The tests document additional ways that this new restriction could
    be worked around and the documentation explains why it might be instead
    considered a feature, but a "fix" is planned for a future change.

    Helped-by: Junio C Hamano <gitster@pobox.com>
    Helped-by: Phillip Wood <phillip.wood123@gmail.com>
    Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

上面的例子也说明历史记录并不是按照时间打印的,具体的要看提交图。

但这样从头开始看很难定位某个提交,此时可以使用since..until的形式指定提交的范围:

$ git log --pretty=short --abbrev-commit master~12..master~10
commit 2fec2d2895
Merge: 3b9a5a33c2 55d9d4bbd0
Author: Junio C Hamano <gitster@pobox.com>

    Merge branch 'jk/perf-lib-test-titles'

commit 55d9d4bbd0
Author: Jeff King <peff@peff.net>

    perf-lib: fix missing test titles in output

commit 3b9a5a33c2
Author: Fangyi Zhou <me@fangyi.io>

    builtin/rebase: remove a redundant space in l10n string

上面的代码就是打印了master~12到master~10之间的所有提交,也就是该分支上之前10次和第11次的提交。而同时--pretty=short调整打印的信息数量,--abbrev-commit则是以缩写散列值打印。

git log -p则可以输出提交引进的补丁或变更:

$ git log -1 -p master
commit 5b71c59bc3b9365075e2a175aa7b6f2b0c84ce44 (HEAD -> master, tag: v2.37.0-rc1, origin/master, origin/main, origin/HEAD)
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 17 17:15:13 2022 -0700

    Git 2.37-rc1

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

diff --git a/Documentation/RelNotes/2.37.0.txt b/Documentation/RelNotes/2.37.0.txt
index f1b93f3c59..99dc7e32f8 100644
--- a/Documentation/RelNotes/2.37.0.txt
+++ b/Documentation/RelNotes/2.37.0.txt
@@ -234,9 +234,8 @@ Fixes since v2.36

  * With a recent update to refuse access to repositories of other
    people by default, "sudo make install" and "sudo git describe"
-   stopped working.  This series intends to loosen it while keeping
-   the safety.
-   (merge b9063afda1 cb/path-owner-check-with-sudo later to maint).
+   stopped working, which has been corrected.
+   (merge 6b11e3d52e cb/path-owner-check-with-sudo-plus later to maint).

  * The tests that ensured merges stop when interfering local changes
    are present did not make sure that local changes are preserved; now
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index c0b5e722dd..22e76c2a59 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh

而上边的-1则会限制输出为一个提交。

而git log中的--stat选项将会列举出提交中所更改的文件以及每个更改的文件中有多少行存在改动。

$ git log --pretty=short --stat master~12..master~10
commit 2fec2d289588a70f8683bfe8f429d9e3d3d31ef5
Merge: 3b9a5a33c2 55d9d4bbd0
Author: Junio C Hamano <gitster@pobox.com>

    Merge branch 'jk/perf-lib-test-titles'

commit 55d9d4bbd044afa004c6962aa50635158dc8719e
Author: Jeff King <peff@peff.net>

    perf-lib: fix missing test titles in output

 t/perf/perf-lib.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 3b9a5a33c2986522736d484da497ccd99d715220
Author: Fangyi Zhou <me@fangyi.io>

    builtin/rebase: remove a redundant space in l10n string

 builtin/rebase.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

而另一个查看对象库中对象信息的命令是git show,可以使用其来查看某个提交:

$ git show HEAD
commit 5b71c59bc3b9365075e2a175aa7b6f2b0c84ce44 (HEAD -> master, tag: v2.37.0-rc1, origin/master, origin/main, origin/HEAD)
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 17 17:15:13 2022 -0700

    Git 2.37-rc1

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

diff --git a/Documentation/RelNotes/2.37.0.txt b/Documentation/RelNotes/2.37.0.txt
index f1b93f3c59..99dc7e32f8 100644
--- a/Documentation/RelNotes/2.37.0.txt
+++ b/Documentation/RelNotes/2.37.0.txt
@@ -234,9 +234,8 @@ Fixes since v2.36

  * With a recent update to refuse access to repositories of other
    people by default, "sudo make install" and "sudo git describe"
-   stopped working.  This series intends to loosen it while keeping
-   the safety.
-   (merge b9063afda1 cb/path-owner-check-with-sudo later to maint).
+   stopped working, which has been corrected.
+   (merge 6b11e3d52e cb/path-owner-check-with-sudo-plus later to maint).

  * The tests that ensured merges stop when interfering local changes
    are present did not make sure that local changes are preserved; now
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index c0b5e722dd..22e76c2a59 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh

 GVF=GIT-VERSION-FILE
-DEF_VER=v2.37.0-rc1 ;# not quite
+DEF_VER=v2.37.0-rc1

 LF='
 '

上面的代码具体打印了本次提交对应提交对象的详细信息,也可以查看某个特定的对象信息:

$ git show b1a8c144e073ba9c5f5d085fa864b5bfb99892fa
#ifndef TR2_DST_H
#define TR2_DST_H

struct strbuf;
#include "trace2/tr2_sysenv.h"

struct tr2_dst {
        enum tr2_sysenv_variable sysenv_var;
        int fd;
        unsigned int initialized : 1;
        unsigned int need_close : 1;
        unsigned int too_many_files : 1;
};

/*
 * Disable TRACE2 on the destination.  In TRACE2 a destination (DST)
 * wraps a file descriptor; it is associated with a TARGET which
 * defines the formatting.
 */
void tr2_dst_trace_disable(struct tr2_dst *dst);

/*
 * Return the file descriptor for the DST.
 * If 0, the dst is closed or disabled.
 */
int tr2_dst_get_trace_fd(struct tr2_dst *dst);

/*
 * Return true if the DST is opened for writing.
 */
int tr2_dst_trace_want(struct tr2_dst *dst);

/*
 * Write a single line/message to the trace file.
 */
void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line);

#endif /* TR2_DST_H */

提交图

Git中通过有向无环图来实现版本库的提交历史记录。

在提交图中,每个节点都代表一个单独的提交,所有边都从子节点指向父节点,形成祖先关系。

并且在提交图中,时间并不是提交图排序的决定因素,因为如果全球协作开发的项目,不同地点的时间加上不同用户主机实际的时间总是不一致的。

提交图具体可以使用gitk工具看一下大概是什么东西:

?上图对应的就是gitk的界面,也很好理解,就不多解释了。

而对于提交图来说:

  • 一般的提交有且只有一个父提交,也就是提交历史记录中的上一次提交
  • 通常一种提交没有父提交,就是初始提交,该提交一般在图的最低端
  • 合并提交会拥有多个父提交

提交范围

通常情况下,可以使用提交范围检查分支或分支的某一部分。

之前使用master~12..master~10就是指明了提交的范围,前边的master~12不包含,master~10包含,该范围标记为start..end,就是end可达,start不可达的范围。而使用git log就是打印HEAD可达的范围。

也可以通过^A排除可达提交集中特定的提交A,git log ^A B就等同于git log A..B。

当如果上面的提交范围设计到分支就会不太容易理解。这里看几个例子:

?上图的topic..master范围为W、X、Y、Z。

??上图的topic..master范围为V之前的提交和V、W、X、Y、Z。

???上图的topic..master范围为W、X、Y、Z。

而提交范围start..end的形式如果没有指定start或end,则缺省项均默认为HEAD。

而与start..end类似的还有start...end,就是两个点和三个点的区别。这种形式表示为对称差,也就是start或end可达但又不是start和end同时可达的提交集合。

????上图的topic...master范围为D、E、F、G、H、I、X、Y、Z。

可以使用如下命令计算A和B的对称差:

$ git rev-list A B --not `(git merge-base --all B)`

而有时也会遇到很抽象的命令,如:

git log ^dev ^topic master

上述命令表示在master分支,不在dev或topic分支上的所有提交。

查找提交

git bisect

该命令一般基于任一搜索条件查找特定的错误提交。

该命令一般用于定位某个错误的提交,比如某次提交存在bug,但之后隔了好久这个bug才出现,那么如果定位该bug处于哪一次提交呢,此时就可以用到git bisect命令

该命令使用二分法来定位bad提交,而用户只需要判断本地提交是good或是bad即可。这里简单看一下该过程。

$ git bisect start

xxx@xxxxxx ~/Desktop/GIT/git (master|BISECTING)
$ git bisect bad

xxx@xxxxxx ~/Desktop/GIT/git (master|BISECTING)
$ git bisect good 1f8496c65f963d2b75ef57dc4f09dbc2f5646bf3
Bisecting: 20 revisions left to test after this (roughly 5 steps)
[99bbf4739d927a3d8183d1fc3f1ee7871aac9fb9] Merge branch 'jc/cocci-cleanup'

xxx@xxxxxx ~/Desktop/GIT/git ((99bbf4739d...)|BISECTING)
$ git bisect good
Bisecting: 9 revisions left to test after this (roughly 3 steps)
[d0d96b8280faf7c22c115374732f50972689c0d2] Merge branch 'js/ci-github-workflow-markup'

xxx@xxxxxx ~/Desktop/GIT/git ((d0d96b8280...)|BISECTING)
$ git bisect good
Bisecting: 4 revisions left to test after this (roughly 2 steps)
[aa11b94ef87050af9e4e0aab64f1ab89636c5be4] Merge branch 'jk/bug-fl-va-list-fix'

xxx@xxxxxx ~/Desktop/GIT/git ((aa11b94ef8...)|BISECTING)
$ git bisect bad
Bisecting: 2 revisions left to test after this (roughly 1 step)
[7281c196b1166f1c00df33948c67b0ef81ba63a9] transfer doc: move fetch.credentialsInUrl to "transfer" config namespace

xxx@xxxxxx ~/Desktop/GIT/git ((7281c196b1...)|BISECTING)
$ git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
[f8535596aa7bd7f6862af3fe6420ac12b17c9912] bug_fl(): correctly initialize trace2 va_list

xxx@xxxxxx ~/Desktop/GIT/git ((f8535596aa...)|BISECTING)
$ git bisect bad
f8535596aa7bd7f6862af3fe6420ac12b17c9912 is the first bad commit
commit f8535596aa7bd7f6862af3fe6420ac12b17c9912
Author: Jeff King <peff@peff.net>
Date:   Thu Jun 16 16:04:25 2022 -0400

    bug_fl(): correctly initialize trace2 va_list

    The code added 0cc05b044f (usage.c: add a non-fatal bug() function to go
    with BUG(), 2022-06-02) sets up two va_list variables: one to output to
    stderr, and one to trace2. But the order of initialization is wrong:

      va_list ap, cp;
      va_copy(cp, ap);
      va_start(ap, fmt);

    We copy the contents of "ap" into "cp" before it is initialized, meaning
    it is full of garbage. The two should be swapped.

    However, there's another bug, noticed by Johannes Schindelin: we forget
    to call va_end() for the copy. So instead of just fixing the copy's
    initialization, let's do two separate start/end pairs. This is allowed
    by the standard, and we don't need to use copy here since we have access
    to the original varargs. Matching the pairs with the calls makes it more
    obvious that everything is being done correctly.

    Note that we do call bug_fl() in the tests, but it didn't trigger this
    problem because our format string doesn't have any placeholders. So even
    though we were passing a garbage va_list through the stack, nobody ever
    needed to look at it. We can easily adjust one of the trace2 tests to
    trigger this, both for bug() and for BUG(). The latter isn't broken, but
    it's nice to exercise both a bit more. Without the fix in this patch
    (but with the test change), the bug() case causes a segfault.

    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

 t/helper/test-trace2.c | 4 ++--
 usage.c                | 8 +++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

上面的过程为:

  • 首先使用git bisect start命令启动该过程
  • 启动该过程后,Git会进入二分模式,并为自己设置一些状态信息,然后使用一个分离的HEAD来管理版本库的当前检出版本。该HEAD本质上是个匿名分支,可用于版本库中来回移动并视需要指定不同的修订版本。
  • 然后执行一个bad提交,因为此时默认在分离HEAD处,可用git bisect bad指定当前HEAD为bad
  • 然后利用git bisect good或git bisect bad对提示的提交指明其为good或为bad
  • 指明后Git会打印当前还有多少提交要确认,因为是二分搜索,每次确认数目都会减少一半
  • 当确认完毕,就会打印bad提交的具体信息

当然这过程中还有其它额外命令。

git bisect log可以打印该过程的log:

$ git bisect log
git bisect start
# bad: [5b71c59bc3b9365075e2a175aa7b6f2b0c84ce44] Git 2.37-rc1
git bisect bad 5b71c59bc3b9365075e2a175aa7b6f2b0c84ce44
# good: [1f8496c65f963d2b75ef57dc4f09dbc2f5646bf3] push: fix capitalisation of the option name autoSetupMerge
git bisect good 1f8496c65f963d2b75ef57dc4f09dbc2f5646bf3
# good: [99bbf4739d927a3d8183d1fc3f1ee7871aac9fb9] Merge branch 'jc/cocci-cleanup'
git bisect good 99bbf4739d927a3d8183d1fc3f1ee7871aac9fb9
# good: [d0d96b8280faf7c22c115374732f50972689c0d2] Merge branch 'js/ci-github-workflow-markup'
git bisect good d0d96b8280faf7c22c115374732f50972689c0d2
# bad: [aa11b94ef87050af9e4e0aab64f1ab89636c5be4] Merge branch 'jk/bug-fl-va-list-fix'
git bisect bad aa11b94ef87050af9e4e0aab64f1ab89636c5be4
# good: [7281c196b1166f1c00df33948c67b0ef81ba63a9] transfer doc: move fetch.credentialsInUrl to "transfer" config namespace
git bisect good 7281c196b1166f1c00df33948c67b0ef81ba63a9
# bad: [f8535596aa7bd7f6862af3fe6420ac12b17c9912] bug_fl(): correctly initialize trace2 va_list
git bisect bad f8535596aa7bd7f6862af3fe6420ac12b17c9912
# first bad commit: [f8535596aa7bd7f6862af3fe6420ac12b17c9912] bug_fl(): correctly initialize trace2 va_list

如果某条bad或good的判定不正确,可以结合git bisect reset和git bisect replay file使用某个文件作为输入重新执行该过程。

也可以使用git bisect visualize命令可视化地检查提交范围内的内容。

如果一切都结束了,则可以使用git bisect reset结束该过程,回到原来的分支上。

$ git bisect reset
Previous HEAD position was f8535596aa bug_fl(): correctly initialize trace2 va_list
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

git blame

该命令能够识别特定提交,通过用户一个文件的每一行最后是谁修改的和哪些提交做出了修改。

$ git blame -L 1, apply.h
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200   1) #ifndef APPLY_H
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200   2) #define APPLY_H
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200   3)
97b989ee3a9 (Denton Liu              2019-09-25 01:20:53 -0700   4) #include "hash.h"
ef3ca95475c (Elijah Newren           2018-08-15 10:54:05 -0700   5) #include "lockfile.h"
ef3ca95475c (Elijah Newren           2018-08-15 10:54:05 -0700   6) #include "string-list.h"
4e9a3252531 (René Scharfe            2022-01-07 13:16:53 +0100   7) #include "strmap.h"
ef3ca95475c (Elijah Newren           2018-08-15 10:54:05 -0700   8)
82ea77eca7a (Nguy?n Thái Ng?c Duy    2018-08-13 18:14:39 +0200   9) struct repository;
82ea77eca7a (Nguy?n Thái Ng?c Duy    2018-08-13 18:14:39 +0200  10)
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  11) enum apply_ws_error_action {
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  12)     nowarn_ws_error,
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  13)     warn_on_ws_error,
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  14)     die_on_ws_error,
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  15)     correct_ws_error
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  16) };
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  17)
71501a71d04 (Christian Couder        2016-08-08 23:02:59 +0200  18) enum apply_ws_ignore {

不过该打印结果看起来似乎太冗余了。

git log -Sstring

git log -Sstring根据给定的string沿着文件的差异历史搜索。通过搜索修订版本间的实际差异,该命令可以找到那些执行改变的提交。

$ git log -Sinclude --pretty=oneline --abbrev-commit apply.h
4e9a325253 apply: use strsets to track symlinks
97b989ee3a apply.h: include missing header
ef3ca95475 Add missing includes and forward declarations
7e1bad24e3 apply: refactor `git apply` option parsing
13b5af22f3 apply: move libified code from builtin/apply.c to apply.{c,h}
71501a71d0 apply: move 'struct apply_state' to apply.h

打印结果对应的左侧每个提交都添加或删除了包含include的行。但是如果某个提交添加和删除了相同数量的含关键词的行,它将不会显示出来。该提交必须有添加和删除数量上的变化才能计数。

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 17:02:52  更:2022-06-26 17:03:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:49:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码