- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
当我在 Git 中指定一个祖先提交对象时,我对 HEAD^
和 HEAD~
感到困惑。
两者都有一个“编号”版本,如 HEAD^3
和 HEAD~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/
我时不时地输入“git”,然后想到别的东西,然后输入例如“git checkout master”。当然,这给我留下了 $ git git checkout master git: 'git' is
我做到了 git 克隆 git://foo.git 光盘富 ...编辑文件.. 现在我想重新开始。我不在乎我已经做出的任何改变,但我不想再次克隆整个巨型 foo.git,只是丢失我所有的更改。我怎
我在我的电脑上开发代码,我的计算节点很少。 为了让我的程序保持同步,我决定使用 git。以前,我以一种单向模式使用它来“下推”从 PC 到计算节点的更改。但是时不时遇到计算节点特有的小bug,现场修复
虽然它似乎什么也没做,但它没有给出任何警告或错误消息。有什么想法吗? 最佳答案 来自 Git 源的注释: /* * Read a directory tree. We currently ignor
我知道如何为这样的 HTTPS 请求提供用户名和密码: git clone https://username:password@remote 但我想知道如何像这样向 Remote 提供用户名和密码:
Git GUI、Git Bash 和 Git CMD 之间有什么区别?我是初学者,为了进行安装,我发现自己通常同时使用 git bash 和 git CMD 最佳答案 Git CMD 就像使用 git
有人能告诉我git中文件索引被删除是什么意思吗?这些文件在我的 VS Code 中标记为红色,但我仍然可以修改文件并将更改推送到将反射(reflect)这些更改的远程存储库。我认为这一切都是在我使用命
我通过 git 子树将 GLFV 库添加到项目中,但出现此警告“看起来您的 git 安装或您的 git-subtree 安装已损坏”。还描述了几个原因,为什么这可能是: 如 git --exec-pa
我有需要外部 git 项目的 repo,但我不想使用子模块,因为我想在 github 上存档所有文件,所以我认为我只是将具有 git repo 的整个目录添加到 git 但它不t 添加里面的 .git
我有需要外部 git 项目的 repo,但我不想使用子模块,因为我想在 github 上存档所有文件,所以我认为我只是将具有 git repo 的整个目录添加到 git 但它不t 添加里面的 .git
我一直在阅读一篇文章,作者在其中指示:在现有存储库中创建一个新存储库,并想知道这是否是他忽略的错误。稍后我会与他核实。 这些是我要检查的条件: 将现有目录制作成仓库的条件,并且已经 checkin 主
我确实在不同的计算机上处理相同的项目,我想知道是否有一种方法可以跟踪该 .git 文件夹,这样我就不必在所有本地文件中重新配置配置文件。 我将所有工作推送到 bitbucket。 最佳答案 不,没
这个问题在这里已经有了答案: How does git store files? (3 个答案) 关闭 9 年前。 我为我的许多项目创建了一个远程存储库,所以它是我的push 的目的地。与 git
应该如何在 git 中查看文件内容的完整历史记录? 一个文件在 git 中的历史很短,存储库通过 git-svn 同步,但在 svn 中的历史很长。 git 中的历史记录到达文件移动的位置。要查看历史
我是confused here ... 如何对修改后的文件进行git commit,以及如何对新文件进行git commit? 还有,你如何在git中单独提交文件? 最佳答案 git 提交过程分为两个
正在搜索 throw SO 来寻找答案。遇到这个似乎没有给出任何答案的旧线程。重新触发此线程,希望有人知道! 有人能告诉我 git subtree 和 git filter-branch 的区别吗?为
我想知道是否有一种方法可以避免在每个 Git 命令的开头键入单词 git。 如果有一种方法可以在打开命令提示符进入 “Git 模式” 后只使用一次 git 命令就好了。 例如: git> 之后,我们键
当您修改工作目录中的文件时,git 会告诉您使用“git add”暂存。 当您向工作目录添加新文件时,git 会告诉您使用“git add”开始跟踪。 我对这两个概念有点困惑,因为我假设跟踪文件的更改
为什么 git://有效 $ git clone git://github.com/schacon/grit.git Cloning into 'grit'... ... Checking conne
我在以下沙箱中练习 git:https://learngitbranching.js.org/?NODEMO 我在两个单独的 session 中运行了两组命令。第一组命令顺序如下: git clone
我是一名优秀的程序员,十分优秀!