缺少git commit

Bor*_*ile 5 git

它总是在工作中发生,某人不小心将某件事提交给了主人,而不是交给了预期的功能分支,然后该人尝试解决该问题,只是使更改突然消失。我搜索了很多东西,找不到文档说明这种情况的发生原因或解决方法。

以下是重现步骤:

$ git init
$ echo hello world > testfile
$ git add testfile
$ git commit -m 'init'
$ git branch A
$ echo abc >> testfile
$ git commit -am 'append abc'
$ git revert HEAD --no-edit
$ git checkout A
$ echo fff > secondfile
$ git add secondfile
$ git commit -m 'Add second file'
$ git cherry-pick master^
Run Code Online (Sandbox Code Playgroud)

此时,git历史记录如下所示:

$ git log --oneline --all --graph --decorate
* ac6f9b4 (HEAD -> A) append abc
* 54be952 Add second file
| * 9ba1f16 (master) Revert "append abc"
| * ef7c8d6 append abc
|/  
* 65a885d init
Run Code Online (Sandbox Code Playgroud)

然后观看当我将分支A重新建立在master之上时发生的情况:

$ git rebase master
$ git log --oneline --all --graph --decorate
* 9d08739 (HEAD -> A) Add second file
* 9ba1f16 (master) Revert "append abc"
* ef7c8d6 append abc
* 65a885d init
Run Code Online (Sandbox Code Playgroud)

在A开头的提交ac6f9b4发生了什么情况?去哪了 为什么不重新应用?

虽然这只是一个小示例,但最后缺少单个提交,但有时我们最终会从长提交链的中间丢失多个提交,然后它们似乎实际上是不可见的:(

jth*_*ill 4

Rebase 不会重新应用已在新基础中应用的提交 - 在这里,这是您的append abc更改。它已经在大师历史中了。这通常是正确的,以至于 git 不做任何评论就这样做了。可以说,在随后的恢复存在的情况下,这一点至少值得一提。

要查看您正在变基的任何内容是否已经是新基础历史记录的一部分(master,此处),

git log --oneline --cherry ...master
Run Code Online (Sandbox Code Playgroud)

并查找=- 标记的提交。这些是 master 中的提交,与您分支中的提交相匹配;rebase 不会重新应用它们。交换master......master查看本地等效项。

如果你想要一个有效的盲变基,第一次切割是

git checkout -B A master
git cherry-pick ..A@{1}      # < added the very important `..` by edit
Run Code Online (Sandbox Code Playgroud)

它只是将 A 移动到 master 上,然后挑选你刚刚留下的所有内容。要忽略合并(您可能应该这样做),请添加--no-merges到cherry-pick,事实证明,当您向cherry-pick请求一个系列时,它只是将整个集合传递给您,git rev-list以便您可以直接使用机器:

git cherry-pick --no-merges ..A@{1}  # just learned now that cherry-pick takes this
Run Code Online (Sandbox Code Playgroud)