gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 01:09:03 27 4
gpt4 key购买 nike

当我在 Git 中指定一个祖先提交对象时,我对 HEAD^HEAD~ 感到困惑。

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

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

最佳答案

经验法则

  • 使用~大多数时候——回到几代人之前,通常是你想要的
  • 使用^关于 merge 提交——因为他们有两个或更多(直接) parent

助记符:

  • 代字号 ~外观上几乎是直线,想直线后退
  • 插入符 ^建议一段有趣的树或岔路口

代字号

“Specifying Revisions” section of the git rev-parse documentation定义 ~作为

<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表示主分支尖端的祖 parent ,有利于 merge 提交的第一个 parent 。

插入符号

Git 历史是非线性的:有向无环图 (DAG) 或树。对于只有一个 parent 的提交,rev~rev^意思是一样的。插入符号选择器在 merge 提交时变得很有用,因为每个提交都是两个或更多 parent 的 child ——并且是从生物学借来的紧张语言。

HEAD^表示当前分支尖端的第一个直接父级。 HEAD^HEAD^1 的缩写, 你也可以解决 HEAD^2依此类推。 same section of the git rev-parse documentation定义为

<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.

例子

这些说明符或选择器可以任意链接,例如topic~3^2在英语中是 merge 提交的第二个父级,它是分支当前尖端的曾祖 parent (三代后)topic .

aforementioned section of the git rev-parse documentation通过概念性的 git 历史记录许多路径。时间通常向下流动。提交 D、F、B 和 A 是 merge 提交。

Here is an illustration, by Jon Loeliger. Both commit nodes B and C are parents of commit node A. Parent commits are ordered left-to-right. (N.B. The git log --graph command displays history in the opposite order.)

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 添加别名这样你就可以像在

$ 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

“Specifying Revisions” in the git rev-parse documentation信息量很大,值得深入阅读。另见 Git Tools - Revision Selection来自书Pro Git .

父提交顺序

提交 89e4fcb0dd来自 git 自己的历史是 merge 提交,如 git show 89e4fcb0dd指示 Merge 标题行,显示直接祖先的对象名称。

commit 89e4fcb0dd01b42e82b8f27f9a575111a26844df
Merge: c670b1f876 649bf3a42f b67d40adbb
Author: Junio C Hamano <gitster@pobox.com>
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>...]'

如果只想提取 parent ,请使用 pretty format %P对于完整的哈希值

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

%p对于简短的 parent 。

$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb

关于git - Git 中的 HEAD^ 和 HEAD~ 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2221658/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com