git-如何为git prune创建无法访问的提交?
我正在为git编写教育材料,我需要演示如何删除“分离的对象”。我想我可以通过使用git-如何为git prune创建无法访问的提交?,git,Git,我正在为git编写教育材料,我需要演示如何删除“分离的对象”。我想我可以通过使用git reset将提交从分支历史中分离出来,从而将其置于分离状态 这将触发git checkout将提交视为已分离,但是git prune将不关心它 我当前分离的提交模拟的设置如下所示: ~ $ mkdir git-prune-demo ~ $ cd git-prune-demo/ ~/git-prune-demo $ git init . Initialized empty Git repository in /
git reset
将提交从分支历史中分离出来,从而将其置于分离状态
这将触发git checkout
将提交视为已分离,但是git prune
将不关心它
我当前分离的提交模拟的设置如下所示:
~ $ mkdir git-prune-demo
~ $ cd git-prune-demo/
~/git-prune-demo $ git init .
Initialized empty Git repository in /Users/kev/Dropbox/git-prune-demo/.git/
~/git-prune-demo $ echo "hello git prune" > hello.txt
~/git-prune-demo $ git add hello.txt
~/git-prune-demo $ git commit -am "added hello.txt"
[master (root-commit) 994b122] added hello.txt
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
~/git-prune-demo $ echo "this is second line txt" >> hello.txt
~/git-prune-demo $ git commit -am "added another line to hello.txt"
[master 5178bec] added another line to hello.txt
1 file changed, 1 insertion(+)
~/git-prune-demo $ git reset --hard 994b122045cf4bf0b97139231b4dd52ea2643c7e
HEAD is now at 994b122 added hello.txt
~/git-prune-demo $ git prune -n
~/git-prune-demo $ nothing
是的,我知道
git prune
通常不作为独立命令使用,本质上是git gc
的子命令 Prune通常不会删除在上一个。。。我忘了,月它会检查本地的回流。Pass--立即过期
以禁用对象删除时的oops保护,但如果您正在编写文档,则建议您养成这样的坏习惯。TL;博士
您需要首先运行git reflog expire--expire unreachable=now
,然后运行git prune--expire now
。即使这样,事情也可能会出问题,不过对于这个特别简单的例子,这可能就足够了
长的
我正在为git编写教育材料,我需要演示git prune如何删除分离的提交
但这不是git prune所做的。它所做的可以产生这种效果,但只有在特定条件下。重要的是,分离提交在Git中并不是一个定义良好的短语:Git对分离头有一个定义,稍后我们将回到这里,但提交本身要么是可到达的,要么是不可到达的。我想你的意思是在这里谈论无法实现的提交
重要的是,gitprune
处理对象,这些对象比提交更通用。Git有四种类型的对象:提交、树、blob和带注释的标记。Git的Git prune
可以删除任何无法访问的对象,只要满足其他几个条件。不过,在我们到达之前,让我们再看几个项目
纠正误解
我想我可以通过使用git reset
将提交从分支历史中分离出来,从而将其置于分离状态
根据定义,如果有某个外部名称直接命名提交(或对象)本身,或者命名我们可以访问给定提交的其他对象,那么提交或任何其他Git对象都是可访问的。(有关这方面的更多信息,请参阅。)使用git reset
,我们可以使只能通过当前分支名称访问的提交变得不可访问。例如,如果只能通过当前分支名称访问提交a123456…
,即,不能通过任何其他分支名称,也不能通过任何标记名称或其他非分支名称引用,则使用git reset
调整当前分支,使其排除a123456…
使该提交无法访问
这将触发git签出,以将提交视为已分离
我想你说的是Git称之为分离的头
分离的头仅仅意味着Git的特殊头引用(存储为名为.Git/HEAD
的文件)包含提交的原始散列ID。相反的情况,我们可以称之为附加头,因为当.git/HEAD
包含分支名称时,这是分离的明显反义词。在这两种情况下,HEAD
表示当前提交;当HEAD
包含分支名称时,HEAD
也指当前分支名称。Git在内部处理这一问题的方式是,它有不同的函数和程序来解析头部
,或者象征性地:
$ git symbolic-ref HEAD
refs/heads/master
或哈希ID:
$ git rev-parse HEAD
c05048d43925ab8edcb36663752c2b4541911231
(对于分离的机头箱,git symbolic ref
产生错误,因为没有分支名称。)
在以下情况下,git checkout
命令将头(附加到某些指定的分支名称):
- 您给它一个分支名称,或者
- 您可以使用它创建并附加到新的分支名称
- 您为它提供了解析为散列ID而不是分支名称的内容(例如,原始散列ID或远程跟踪名称,如
),或者origin/master
- 您可以使用
标志强制分离磁头,即使它通常会连接磁头--detach
头
,但在添加下一个复杂度之前,我们将从这些名称开始
Git的对象模型和对对象的引用
很好地描述了引用如何使提交可访问。不过,它没有提到,一般来说,引用可以指定任何对象的哈希ID,而不仅仅是提交。这是因为它关注的是分支,而不仅仅是任何旧对象,而且分支名称(refs/heads/*
)和远程跟踪名称(refs/remotes/*
)都被限制为仅指向提交。它也没有详细介绍提交中的内容,即Git如何存储文件和文件名。这就是树和blob对象的作用
每个提交都包含单个树对象的哈希ID。树对象包含一系列三值项:mode、name和hash-ID
... <- commit a1234... <-- branchname
|
v
tree 07f39...: (100644, README.txt, 531c2...); (040000, subdir, ...)
| |
v |
blob 531c2...: data for README.txt |
|
v
tree ...: ...
git reflog expire --expire-unreachable=now --all
git prune --expire now