gpt4 book ai didi

git - git reset --soft 只更改哈希值吗?

转载 作者:太空狗 更新时间:2023-10-29 14:35:18 27 4
gpt4 key购买 nike

在这篇文章中,作者很好地解释了 git reset 的 3 个选项(soft、mixed、hard): https://www.atlassian.com/git/tutorials/undoing-changes/git-reset

他使用“三棵树”作为一种手段来表示 1) 工作树,2) 暂存区,3) “提交历史/提交引用”:

--hard重置 (1),(2),(3);

--mixed重置 (2) 和 (3);

--soft仅更改 (3)。

它是 (3) 实际代表什么我有点不清楚。我可以看到 git reset --soft可用于更改分支指向的提交。但我不知道为什么这里要用历史这个词。除了分支和 HEAD 都引用的提交之外,到底修改了什么?

编辑:特别是 git reset --soft <SHA1> 编辑 i) .git/refs/heads/master 中的哈希值文件和 ii) .git/HEAD 中的哈希值没有别的吗?

最佳答案

既然你问的是具体的实现——我认为这实际上更容易解释——看看.git/HEAD中的实际内容,当你在一个分支上时:

$ cat .git/HEAD
ref: refs/heads/master
$ git checkout -b new
Switched to a new branch 'new'
$ cat .git/HEAD
ref: refs/heads/new
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ cat .git/HEAD
ref: refs/heads/master

所以,只要我“在一个分支上”为 git status会说,分支名称——引用的全名,真的——在.git/HEAD中。 .所以.git/HEAD不会改变,也不需要改变。

是否.git/refs/heads/master甚至存在问题更多:

$ cat .git/refs/heads/master
cat: .git/refs/heads/master: No such file or directory
$ git rev-parse master
b5101f929789889c2e536d915698f58d5c5c6b7a
$ grep master .git/packed-refs
b5101f929789889c2e536d915698f58d5c5c6b7a refs/heads/master
b5101f929789889c2e536d915698f58d5c5c6b7a refs/remotes/origin/master

这里发生的事情是 Git 打包 我的引用名称,所以不再有普通文件:refs/heads/master而是存储在 .git/packed-refs 中,作为几行之一(在这种情况下,另一条匹配行是 refs/remotes/origin/master )。

也就是说,reference-to-hash-ID 映射存储在某个数据库 中,不一定在简单文件中。 (不过,packed-refs“数据库”仍然非常简单。)

不过,要回答您的最终问题,它只是:git reset --soft <hash><hash>进入 name-to-hash-ID 映射。即使我们使用名称而不是哈希 ID,也是如此:

$ git checkout new
$ git reset --soft master~3

名字new现在引用与名称 master~3 相同的提交哈希 ID指的是:

$ git rev-parse new
371820d5f1bb3c3e691ad21cee652c02c36ea758
$ git rev-parse master~3
371820d5f1bb3c3e691ad21cee652c02c36ea758

(将新哈希 ID 写入名称 new 的行为发生在当前版本的 Git 中,通过写入简单文件 .git/refs/heads/new 来覆盖打包引用的数据库,但您不应该依赖于此 -使用 git rev-parsegit update-ref 代替。)

自从我创建了new来自 master ,以上,这仅具有移动名称 new 的效果返回三个第一父跳(master~3)。这意味着 newmaster的祖先,所以:

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git branch -d new
Deleted branch new (was 371820d5f1).

... 所以 Git 可以简单地删除名称 new现在,因为它已完全 merge 到 master .

But I don't know why the word history is being used here.

“历史”并不是最好的词。要真正理解这一点,请通读网站 Think Like (a) Git .这里的关键概念是可达性。更改存储在分支名称下的提交哈希 ID,如 git reset确实如此,更改了可到达的提交集。如果集合增长,则可以访问更多提交;如果缩小,则可以到达的提交更少;如果它保持相同大小,则可以访问相同的数量 提交,但集合本身可能相同也可能不同。

“历史”,笼统而含糊地说,是存储库中的提交集,或可从某个名称访问的提交集,或可从某个名称访问的提交的某些子集。使用这些松散定义中的一些但不是全部,移动名称会改变历史。

关于git - git reset --soft 只更改哈希值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54438656/

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