在 git rebase 期间如何引用当前编辑的提交的原件?
How can I reference the original of a currently edited commit during git rebase?
我想在 git rebase -i
期间获取有关当前编辑提交的原始信息的一些信息,但 HEAD 引用了不同的提交哈希。如何引用原始提交?
示例:
$ git rebase -i upstream
(选择 "edit" 进行提交)
[detached HEAD befa32f] Previous commit message
1 file changed, 121 insertions(+), 1 deletion(-)
rewrite README.md (100%)
Stopped at 9a1e25391e5a53965c80dc69e1285dba7c59f893... Current commit message
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
现在我想引用 9a1e25391e5a53965c80dc69e1285dba7c59f893
但 HEAD 具有不同的哈希值和不同的属性,尽管它似乎是相同的提交:
$ cat .git/HEAD
1414539371fe6b122d5f326bc7b344eea761dc50
这是从哪里来的,我怎样才能引用原始提交?
就其价值而言,根据定义 HEAD
总是 "current commit"——或者说 "the current commit is whatever HEAD
says it is" 可能更准确.
至多 "normal" 次,HEAD
包含对分支名称的引用:例如,如果您 cat .git/HEAD
(或在文件查看器或编辑器中打开它),您您会看到 ref: refs/heads/master
或 ref: refs/heads/develop
,具体取决于您所在的分支。在这种情况下,您位于指定的分支上,当前提交是该分支的尖端。1
如果您使用 git checkout --detach
或给 git checkout
原始提交 SHA-1,另一方面,git 会让您进入 "detached HEAD" 模式。虽然这听起来像是 18 世纪法国大革命的场景,但它只是意味着 HEAD
直接指代原始 SHA-1。在这种情况下,SHA-1 是当前提交。
当你 运行 git rebase -i
并让它在提交时停止(通过将处置设置为 edit
),rebase 使你处于 "detached HEAD" 模式,当前提交—a.k.a。 HEAD
—作为您现在可以编辑的提交。此时,您可以对树进行一些更改并执行 git add
,例如:您对树所做的更改然后 add
现在位于临时区域中。如果您接下来要做的是 git commit --amend
,git 进行新提交,其父级与当前提交的父级相同:
old <-- HEAD before `git commit --amend`
/
...--o
\
new <-- HEAD after `git commit --amend`
请注意,在 git commit --amend
之后,HEAD
仍然是 "the current commit"(根据定义),它不再是您要更改的提交(上面的 old
).
在这一点上,没有一种正确的方法可以通过名称引用 old
的 SHA-1,但是有几种方法可以找到它:例如 git log --graph --decorate --oneline HEAD ORIG_HEAD
,将显示可以从 HEAD
(你现在所在的位置,提交 new
)和 ORIG_HEAD
(记录你第一次启动 rebase 时的位置:这不一定是提交 old
但它将在其历史记录中提交 old
)。
例如,当停在 rebase -i HEAD~2
时,我添加了一个新文件并使用 git commit --amend
提交了它,结果是:
$ git log --graph --decorate --oneline HEAD ORIG_HEAD
* 9daa414 (HEAD) mod1, amended
| * bd49ea7 (master) mod2
| * f071da2 mod1
|/
* 28c4ee8 initial
或者您可以依赖 git 内部结构(随着时间的推移发生了变化,因此不能保证这对您有用):
$ ls .git/rebase-merge
amend git-rebase-todo.backup onto
author-script head-name orig-head
done interactive patch
end message quiet
git-rebase-todo msgnum stopped-sha
在这里,rebase-merge/stopped-sha
具有我停止编辑时当前提交的 SHA-1,因此:
$ git rev-parse rebase-merge/stopped-sha
f071da26a90f14945d89ccdeed3c278e9b499a2e
与 一样,查找 old
的最简单方法可能是使用 git 的引用日志。由于我们刚刚创建了提交 new
并移动了 HEAD
,旧提交 old
的 SHA-1 只是 HEAD@{1}
。当然,如果您进行多次提交(例如,多次 --amend
试图使其完美),2 old
可能低于 HEAD{2}
, HEAD@{3}
,或更高。
请注意,此时,当我执行 git rebase --continue
时,git 所做的是应用剩余的项目(在上面的 ls
输出中的 rebase-merge/git-rebase-todo
) 到当前 HEAD
。如果一切顺利,rebase
做的最后一件事是将当前分支(在 rebase-merge/head-name
中,在本例中包含 refs/heads/master
)重新指向最尖端的提交made,然后恢复HEAD
的间接引用状态,这样我现在就在分支的新提示master
:
$ git rebase --continue
Successfully rebased and updated refs/heads/master.
1或者,作为一种特殊情况,如果 HEAD
包含对分支的引用但该分支尚不存在,则表示您在一个"unborn branch"。在这种情况下,没有 no 当前提交,但是当您进行新提交时,它将是新的、现在诞生的分支上的初始提交。通常人们只会在 git init
之后在新存储库中创建第一个提交时看到这一点。但是,在 git 版本 1.7.2 及更高版本中,使用 git checkout --orphan <branchname>
创建一个新的未出生分支,以便您可以创建一个新的历史记录,使其与现有存储库中的现有历史记录无关。
2我不能代表任何人说话,但我一直这样做。 :-)
我想在 git rebase -i
期间获取有关当前编辑提交的原始信息的一些信息,但 HEAD 引用了不同的提交哈希。如何引用原始提交?
示例:
$ git rebase -i upstream
(选择 "edit" 进行提交)
[detached HEAD befa32f] Previous commit message
1 file changed, 121 insertions(+), 1 deletion(-)
rewrite README.md (100%)
Stopped at 9a1e25391e5a53965c80dc69e1285dba7c59f893... Current commit message
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
现在我想引用 9a1e25391e5a53965c80dc69e1285dba7c59f893
但 HEAD 具有不同的哈希值和不同的属性,尽管它似乎是相同的提交:
$ cat .git/HEAD
1414539371fe6b122d5f326bc7b344eea761dc50
这是从哪里来的,我怎样才能引用原始提交?
就其价值而言,根据定义 HEAD
总是 "current commit"——或者说 "the current commit is whatever HEAD
says it is" 可能更准确.
至多 "normal" 次,HEAD
包含对分支名称的引用:例如,如果您 cat .git/HEAD
(或在文件查看器或编辑器中打开它),您您会看到 ref: refs/heads/master
或 ref: refs/heads/develop
,具体取决于您所在的分支。在这种情况下,您位于指定的分支上,当前提交是该分支的尖端。1
如果您使用 git checkout --detach
或给 git checkout
原始提交 SHA-1,另一方面,git 会让您进入 "detached HEAD" 模式。虽然这听起来像是 18 世纪法国大革命的场景,但它只是意味着 HEAD
直接指代原始 SHA-1。在这种情况下,SHA-1 是当前提交。
当你 运行 git rebase -i
并让它在提交时停止(通过将处置设置为 edit
),rebase 使你处于 "detached HEAD" 模式,当前提交—a.k.a。 HEAD
—作为您现在可以编辑的提交。此时,您可以对树进行一些更改并执行 git add
,例如:您对树所做的更改然后 add
现在位于临时区域中。如果您接下来要做的是 git commit --amend
,git 进行新提交,其父级与当前提交的父级相同:
old <-- HEAD before `git commit --amend`
/
...--o
\
new <-- HEAD after `git commit --amend`
请注意,在 git commit --amend
之后,HEAD
仍然是 "the current commit"(根据定义),它不再是您要更改的提交(上面的 old
).
在这一点上,没有一种正确的方法可以通过名称引用 old
的 SHA-1,但是有几种方法可以找到它:例如 git log --graph --decorate --oneline HEAD ORIG_HEAD
,将显示可以从 HEAD
(你现在所在的位置,提交 new
)和 ORIG_HEAD
(记录你第一次启动 rebase 时的位置:这不一定是提交 old
但它将在其历史记录中提交 old
)。
例如,当停在 rebase -i HEAD~2
时,我添加了一个新文件并使用 git commit --amend
提交了它,结果是:
$ git log --graph --decorate --oneline HEAD ORIG_HEAD
* 9daa414 (HEAD) mod1, amended
| * bd49ea7 (master) mod2
| * f071da2 mod1
|/
* 28c4ee8 initial
或者您可以依赖 git 内部结构(随着时间的推移发生了变化,因此不能保证这对您有用):
$ ls .git/rebase-merge
amend git-rebase-todo.backup onto
author-script head-name orig-head
done interactive patch
end message quiet
git-rebase-todo msgnum stopped-sha
在这里,rebase-merge/stopped-sha
具有我停止编辑时当前提交的 SHA-1,因此:
$ git rev-parse rebase-merge/stopped-sha
f071da26a90f14945d89ccdeed3c278e9b499a2e
与 old
的最简单方法可能是使用 git 的引用日志。由于我们刚刚创建了提交 new
并移动了 HEAD
,旧提交 old
的 SHA-1 只是 HEAD@{1}
。当然,如果您进行多次提交(例如,多次 --amend
试图使其完美),2 old
可能低于 HEAD{2}
, HEAD@{3}
,或更高。
请注意,此时,当我执行 git rebase --continue
时,git 所做的是应用剩余的项目(在上面的 ls
输出中的 rebase-merge/git-rebase-todo
) 到当前 HEAD
。如果一切顺利,rebase
做的最后一件事是将当前分支(在 rebase-merge/head-name
中,在本例中包含 refs/heads/master
)重新指向最尖端的提交made,然后恢复HEAD
的间接引用状态,这样我现在就在分支的新提示master
:
$ git rebase --continue
Successfully rebased and updated refs/heads/master.
1或者,作为一种特殊情况,如果 HEAD
包含对分支的引用但该分支尚不存在,则表示您在一个"unborn branch"。在这种情况下,没有 no 当前提交,但是当您进行新提交时,它将是新的、现在诞生的分支上的初始提交。通常人们只会在 git init
之后在新存储库中创建第一个提交时看到这一点。但是,在 git 版本 1.7.2 及更高版本中,使用 git checkout --orphan <branchname>
创建一个新的未出生分支,以便您可以创建一个新的历史记录,使其与现有存储库中的现有历史记录无关。
2我不能代表任何人说话,但我一直这样做。 :-)