Git 中的 HEAD^ 和 HEAD~ 有什么区别?

2024-01-04

当我在 Git 中指定祖先提交对象时,我很困惑HEAD^ and HEAD~.

两者都有一个“编号”版本,例如HEAD^3 and HEAD~2.

它们对我来说看起来非常相似或相同,但是波浪号和插入符号之间有什么区别吗?


经验法则

  • Use ~大多数时候——可以追溯到几代人之前,通常是你想要的
  • Use ^在合并提交上 - 因为它们有两个或更多(直接)父母

助记符:

  • Tilde ~外观近乎直线,想直线向后走
  • Caret ^建议树上有趣的部分或岔路口

Tilde

The 的“指定修订”部分git rev-parse文档 https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltrevgtltngtemegemmaster3em定义~ as

<rev>~<n>, e.g. master~3
A suffix ~<n> to a revision parameter means the commit object that is the nth generation ancestor of the named commit object, following only the first parents. For example, <rev>~3 is equivalent to <rev>^^^ which is equivalent to <rev>^1^1^1

您可以联系任何提交的父母,而不仅仅是HEAD。您还可以向后移动几代人:例如,master~2表示主分支尖端的祖父母,在合并提交时支持第一个父分支。

Caret

Git 历史是非线性的:有向无环图 (DAG) 或树。对于只有一个父级的提交,rev~ and rev^意思是一样的。插入符号选择器对于合并提交非常有用,因为每个提交都是两个或多个父母的孩子 - 并且从生物学借用了语言。

HEAD^意思是第一个即时当前分支尖端的父级。HEAD^是缩写HEAD^1,您还可以解决HEAD^2等等。这的同一部分git rev-parse文档 https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltrevgtemegemHEADv1510em将其定义为

<rev>^, e.g. HEAD^, v1.5.1^0
A suffix ^ to a revision parameter means the first parent of that commit object. ^<n> means the nth parent ([e.g.] <rev>^ is equivalent to <rev>^1). As a special rule, <rev>^0 means the commit itself and is used when <rev> is the object name of a tag object that refers to a commit object.

Examples

这些说明符或选择器可以任意链接,e.g., topic~3^2英文是合并提交的第二个父级,它是分支当前尖端的曾祖父母(三代人之前)topic.

The 上述部分的git rev-parse文档 https://git-scm.com/docs/git-rev-parse#_specifying_revisions追溯了名义上的 git 历史的许多路径。时间总体上向下流动。提交 D、F、B 和 A 是合并提交。

这是 Jon Loeliger 绘制的插图。提交节点 B 和 C 都是提交节点 A 的父节点。父节点提交按从左到右的顺序排列。 (注:git log --graph命令以相反的顺序显示历史记录。)

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A

A =      = A^0
B = A^   = A^1     = A~1
C = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

运行下面的代码来创建一个 git 存储库,其历史记录与引用的插图相匹配。

#! /usr/bin/env perl

use strict;
use warnings;
use subs qw/ postorder /;
use File::Temp qw/ mkdtemp /;

my %sha1;
my %parents = (
  A => [ qw/ B C /               ],
  B => [ qw/     D E F /         ],
  C => [ qw/         F /         ],
  D => [ qw/           G H /     ],
  F => [ qw/               I J / ],
);

sub postorder {
  my($root,$hash) = @_;
  my @parents = @{ $parents{$root} || [] };
  postorder($_, $hash) for @parents;
  return if $sha1{$root};
  @parents = map "-p $sha1{$_}", @parents;
  chomp($sha1{$root} = `git commit-tree @parents -m "$root" $hash`);
  die "$0: git commit-tree failed" if $?;
  system("git tag -a -m '$sha1{$root}' '$root' '$sha1{$root}'") == 0 or die "$0: git tag failed";
}

$0 =~ s!^.*/!!;  # / fix Stack Overflow highlighting
my $repo = mkdtemp "repoXXXXXXXX";
chdir $repo or die "$0: chdir: $!";
system("git init") == 0               or die "$0: git init failed";
chomp(my $tree = `git write-tree`);      die "$0: git write-tree failed" if $?;

postorder 'A', $tree;
system "git update-ref HEAD   $sha1{A}"; die "$0: git update-ref failed" if $?;
system "git update-ref master $sha1{A}"; die "$0: git update-ref failed" if $?;

# for browsing history - http://blog.kfish.org/2010/04/git-lola.html
system "git config alias.lol  'log --graph --decorate --pretty=oneline --abbrev-commit'";
system "git config alias.lola 'log --graph --decorate --pretty=oneline --abbrev-commit --all'";

它仅在新的一次性存储库中添加别名git lol and git lola http://blog.kfish.org/2010/04/git-lola.html这样你就可以查看历史记录

$ git lol
*   29392c8 (HEAD -> master, tag: A) A
|\
| * a1ef6fd (tag: C) C
| |
|  \
*-. \   8ae20e9 (tag: B) B
|\ \ \
| | |/
| | *   03160db (tag: F) F
| | |\
| | | * 9df28cb (tag: J) J
| | * 2afd329 (tag: I) I
| * a77cb1f (tag: E) E
*   cd75703 (tag: D) D
|\
| * 3043d25 (tag: H) H
* 4ab0473 (tag: G) G

请注意,在您的计算机上,SHA-1 对象名称将与上面的名称不同,但标签允许您按名称处理提交并检查您的理解。

$ git log -1 --format=%f $(git rev-parse A^)
B
$ git log -1 --format=%f $(git rev-parse A~^3~)
I
$ git log -1 --format=%f $(git rev-parse A^2~)
F

The 中的“指定修订”git rev-parse文档 https://git-scm.com/docs/git-rev-parse#_specifying_revisions充满了重要的信息,值得深入阅读。也可以看看Git 工具 - 修订选择 https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection从书中Pro Git https://git-scm.com/book/en/v2/.

父级提交的顺序

提交89e4fcb0dd https://github.com/git/git/commit/89e4fcb0dd01b42e82b8f27f9a575111a26844df从 git 自己的历史来看,是一个合并提交,如下git show 89e4fcb0dd指示显示直接祖先对象名称的合并标题行。

commit 89e4fcb0dd01b42e82b8f27f9a575111a26844df
Merge: c670b1f876 649bf3a42f b67d40adbb
Author: Junio C Hamano <[email protected] /cdn-cgi/l/email-protection>
Date:   Mon Oct 29 10:15:31 2018 +0900

    Merge branches 'bp/reset-quiet' and 'js/mingw-http-ssl' into nd/config-split […]

我们可以通过询问确认订单git rev-parse按顺序显示 89e4fcb0dd 的直接父母。

$ git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3
c670b1f876521c9f7cd40184bf7ed05aad843433
649bf3a42f344e71b1b5a7f562576f911a1f7423
b67d40adbbaf4f5c4898001bf062a9fd67e43368

查询不存在的第四个父级会导致错误。

$ git rev-parse 89e4fcb0dd^4
89e4fcb0dd^4
fatal: ambiguous argument '89e4fcb0dd^4': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

如果您只想提取父母,请使用漂亮的格式 https://git-scm.com/docs/git-log#_pretty_formats %P对于完整的哈希值

$ git log -1 --pretty=%P 89e4fcb0dd
c670b1f876521c9f7cd40184bf7ed05aad843433 649bf3a42f344e71b1b5a7f562576f911a1f7423 b67d40adbbaf4f5c4898001bf062a9fd67e43368

or %p对于简短的父母。

$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Git 中的 HEAD^ 和 HEAD~ 有什么区别? 的相关文章

  • 获取最新远程提交的 SHA1 [重复]

    这个问题在这里已经有答案了 可能的重复 git bash 如何检查是否有新的提交可用 https stackoverflow com questions 6006759 git bash how to check if theres a n
  • 如何升级 Windows 中 git svn 使用的 SVN 版本?

    我的公司正在将SVN升级到1 7 检查git svn version显示正在使用的SVN版本是1 4 6 我想获得 git svn 使用的 SVN 版本接近 1 7 但是 我没有看到有关更新 git svn 使用的 SVN 版本 在 Win
  • Visual Studio Code 内置故事,用于查看 git 提交历史记录并对其内容进行比较

    In this https stackoverflow com questions 37899765 how can i view the git history in visual studio code 60013101 noredir
  • 致命:不是 git 存储库(或任何父目录):.git [重复]

    这个问题在这里已经有答案了 当我尝试推送 github com 上的现有存储库时 当我输入命令时 网站提示我将其输入终端 我收到了以下致命错误消息 Not a git repository or any of the parent dire
  • git Blame:合并后正确的作者

    GIT 合并引入了新的提交 这会导致 git Blame 问题 合并的行似乎是由进行合并的开发人员提交的 我可以理解这种情况冲突的变化 因为他解决了冲突 但是有没有办法让非冲突线路不发生这种情况呢 一些 git Blame 的选择 如果没有
  • 如何将 GIT 调用的输出获取到批处理脚本中的变量中?

    我有一个 git 命令来获取当前存储库的最新 SHA 如下所示 git log pretty format H n 1 我有一个 Windows 批处理脚本 我想按如下方式使用它 SET CURRENT SHA 但我不知道如何将从 git
  • 在 Azure DevOps 中为 Wix MSI 文件生成 GUID

    我正在为 Web 服务器应用程序和 Sitecore 前端应用程序设置 Wix 安装程序 我的问题并非特定于 Web 服务器或 Sitecore 我的问题是 Wix 以及如何使用它进行持续交付 1 Wix 需要每个文件和产品本身的 GUID
  • git 如何查找分支源自的提交哈希

    假设我从主分支分支到主题分支 然后在主题分支上进行了一些提交 是否有命令告诉我主题分支源自的主分支上的提交哈希 理想情况下 我不必知道我做了多少次提交 试图避免 HEAD 5 我已经用谷歌搜索过 但似乎无法找到答案 谢谢 use git m
  • 我可以忽略全局 .gitignore 吗?

    我的全局 gitignore 一般都很棒 但对于这个一次性项目 我不希望应用全局规则 如何删除这个怪异存储库的全局 gitignore 规则 在您的存储库中运行此命令 git config local core excludesfile f
  • 更改先前提交的作者姓名:快进推送被拒绝

    我最近在 GitHub 上打开了一个存储库 我是 Git 新手 与新人一样 我使用默认名称和电子邮件进行提交 按照最佳菜鸟传统 我发现五次提交为时已晚 现在乐趣开始了 因为我开始搜索有关如何更改这些提交的作者和提交者名称的信息 美好的 我基
  • 如何使用 git --word-diff 显示空格差异?

    为了说明问题 参见diff https github com nim lang Nim commit 47c7fd037ed28b7de3d120b003d059d30e18f128 diff split diff 8af935b2312d
  • 尝试配置 GIT 时 Eclipse 没有响应

    Windows 10 专业版 64 位SSD金士顿 i5 4690Eclipse 版本 全部工作空间 空问题 每次我尝试配置 TEAM gt GIT gt 配置或尝试导入 创建本地 远程 git 时 Eclipse 都会冻结 直到我强制用任
  • 使用 GitHub,在添加现有存储库时如何推送所有分支?

    我创建了一个新的 GitHub 存储库 我想将现有的存储库放在那里 我按照说明操作 cd existing git repo git remote add origin email protected cdn cgi l email pro
  • git am 和 git apply 有什么区别?

    Both git am https git scm com docs git am and git apply https git scm com docs git apply可用于应用补丁 看起来git am自动提交 而git apply
  • 为什么 Git Bash 无法运行我的可执行文件?

    I am on git for windows https github com git for windows 吉特 巴什 我无法在命令行上运行可执行文件 Pedr Abc 07 MINGW64 c dev ls sqlite3 exe
  • 如何在现有裸存储库中创建引用日志信息

    您可能已经知道 默认情况下 git 不会为新的裸存储库启用引用日志更新 问题是 我有一个很长的历史存储库 但它是在我设置 logAllRefUpdates 标志之前创建的 现在我希望其他应用程序可以使用该信息 如何通过对现有存储库进行最少的
  • 有什么方法可以从提交的消息中获取提交的 SHA 值吗?

    当做一个git tag 我并不总是擅长记住 HEAD 6 例如 是包含的还是排他的 鉴于我的大多数提交都以问题号为前缀 我想知道是否有一些神奇的命令可以从其消息的一部分中搜索提交 SHA 我知道这很容易做到git log并从那里开始工作 但
  • git 清除远程仓库

    如果我将错误的初始提交 或多个 推送到远程存储库 并且只想清除 销毁它 我可以通过命令来完成吗 将其从服务器中完全删除非常重要 这样它就不会占用磁盘空间 例如 今天我推送了一个完整的 Visual Studio 项目 其中包含 dll sd
  • 是否可以使用“git gc”来打包引用日志对象?

    正如答案所暗示的https stackoverflow com a 32025729 https stackoverflow com a 32025729我已经配置了远程裸仓库 git config gc pruneExpire never
  • Git 忽略本地文件更改

    我都尝试过 git update index assume unchanged config myconfig and editing git info exclude并添加config myconfig 然而 当我执行 git pull

随机推荐

  • 如何在提取元素时跳过“#”号而不循环?

    我想从这个数据集中获取一个新的data frame 但是有些行之间有一些带有 的描述 有些行包含 符号 我可以在条件 substr x 1 下使用 for 循环 1 和 gsub 使用正则表达式来获得我需要的结果 我的问题是我是否可以在没有
  • 如何在 python 中使用 kNN 动态时间扭曲

    我有一个带有两个标签的时间序列数据集 0 and 1 我在用动态时间扭曲 DTW 作为使用 k 最近邻 kNN 进行分类的相似性度量 如这两篇精彩的博客文章中所述 https nbviewer jupyter org github mark
  • LaTeX:美元符号与 \( \)

    有什么理由更喜欢语法 myformula 到平常的 myformula 在乳胶中 Edit 同样的问题被问到并得到了回答tex stackexchange https tex stackexchange com questions 510
  • 使用 Javascript 更新 JSON 对象

    如何使用 javascript 或 Jquery 动态更新以下 JSON 对象 var jsonObj Id 1 Username Ray FatherName Thompson Id 2 Username Steve FatherName
  • 当进程内存不足时删除大型 Javascript 对象

    我是这种javascript的新手 所以我会给出一个简短的解释 我内置了一个网络抓取工具Nodejs收集 相当多的 数据 并用Cheerio 基本上jQuery for Node 创建一个对象然后将其上传到 mongoDB 它工作得很好 除
  • React:向现有组件添加道具

    我正在尝试找出如何使用附加道具克隆现有元素 以供参考 this mainContent
  • rtmp和rtsp协议有什么区别?

    我只是想知道 rtsp 和 rtmp 协议之间有什么区别 如果我的服务器上有 mp3 并且我正在我的 Android 中使用 http 播放它 那么它们在工作中有何不同 在android中如果我想实现rtmp或rtsp 哪个是最好的 and
  • SQL Server R2 SSRS 上的 Reporting Services 权限

    当我尝试访问 SQL Server 2008 R2 上的 SSRS 时 出现以下错误 我不确定有多少其他人已经开始使用 SQL 2008 R2 SSRS 但当我尝试访问报告服务器 url 时遇到以下错误 用户没有所需的权限 验证是否已授予足
  • Java 服务器 -- 使用 POST 发送 Push 到 google Firebase Cloud

    在我测试了推送通知与 Postman 的配合后 我想在我的应用程序中发送消息时向 FCM 发送推送请求 调用的函数将访问我的 Java 服务器并调用如下函数 POST Consumes MediaType APPLICATION JSON
  • 如何将 2 路数据绑定与模型驱动表单结合起来?

    在角度 2 中 构建形式的一种可能性是模型驱动方式 据我了解 控件失去了 2 路数据绑定 这与 ngModel 的模板驱动方式相反 将 2 路数据绑定与模型驱动表单相结合的最佳方式是什么 我尝试将模型绑定与 value 一起使用
  • 服务器重启后 Liferay 调度程序不工作

    我正在使用下面的代码安排工作 Controller RequestMapping VIEW public class MyController RenderMapping public String defaultView try Stri
  • 在 Javascript 中使用 Ruby 变量(在应用程序视图中)

    目前 我有一个可以通过名为的视图访问的 ruby 变量 json 其中包含我需要的 JSON 格式的信息 但是 我想将其传递到脚本区域 例如 有什么办法可以做到这一点吗 假设您提到的脚本标签位于 html erb 视图中 您可以使用以下命令
  • 来自 Python 子进程的实时输出/流

    我正在使用 Python 及其子进程库来使用 strace 检查调用的输出 具体如下 subprocess check output strace str processname 但是 这只能给我输出after被调用的子进程已经完成 这对我
  • 制作索引控制数组?

    C 是否有索引控制数组 我想放置一个 按钮数组 例如有 5 个按钮 它只使用一个事件处理程序来处理所有这 5 个控件的索引 就像 VB6 那样 否则我必须为这 5 个按钮中的每一个编写一个额外的事件处理程序 如果我有 100 个按钮 我需要
  • 在 Sphinx 中生成外部链接

    我想链接到 Sphinx 文档中的某个 URL a href http some url blah a 我在文档中发现了类似的内容 http sphinx doc org ext extlinks html http sphinx doc
  • 在 Swift 1.2 的 init 方法中将 self 作为参数传递

    下面的课程有一个 let 属性声明为隐式解包变量 这之前适用于 Xcode 6 2 class SubView UIView let pandGestureRecognizer UIPanGestureRecognizer required
  • 如何检查 MVC Core 配置文件中的某个部分是否存在?

    如何检查加载的 ASP NET Core 配置文件中的特定部分是否存在 我有一个 JSON 配置文件 我将其加载到其中Startup类通过ConfigurationBuilder AddJsonFile method 该 JSON 文件是一
  • 使用 ggplot 函数将 geom_path 添加到箱线图时出错

    我打算创建一个箱线图并突出显示成对比较的显着性水平 这已在一个上一篇文章 https stackoverflow com questions 14958159 indicating the statistically significant
  • 在 AddObject 之后、在 SaveChanges 之前查询对象?

    在实体框架中 是否可以在调用 SaveChanges 方法之前查询刚刚使用 添加对象 添加到上下文的对象 Thanks 要持久化一个实体 您通常将其添加到它的DbSet在上下文中 例如 var bar new Bar bar Name fo
  • Git 中的 HEAD^ 和 HEAD~ 有什么区别?

    当我在 Git 中指定祖先提交对象时 我很困惑HEAD and HEAD 两者都有一个 编号 版本 例如HEAD 3 and HEAD 2 它们对我来说看起来非常相似或相同 但是波浪号和插入符号之间有什么区别吗 经验法则 Use 大多数时候