git - 缺少 git 提交

标签 git

在工作中经常会发生这样的情况,有人不小心将某些东西提交给 master 而不是预期的功能分支,然后这个人试图解决它,结果更改突然消失了。我进行了大量搜索,但找不到任何文档来阐明为什么会发生这种情况,或者如何补救这种情况。

重现步骤如下:

$ 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^

此时 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

然后观察当我在 master 之上 rebase 分支 A 时会发生什么:

$ 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

A 开头的提交 ac6f9b4 发生了什么?它去哪儿了?为什么没有重新应用?

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

最佳答案

Rebase 不会重新应用已经在新基础中应用的提交——在这里,这是您的append abc 更改。它已经在主历史中。这通常是正确的,以至于 git 不加评论地这样做。可以说,在随后的还原情况下,它至少值得一提。

查看你要 rebase 的任何东西是否已经是新基历史的一部分(master,在这里),

git log --oneline --cherry ...master

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

如果你想要一个有效的盲 rebase ,第一步是

git checkout -B A master
git cherry-pick ..A@{1}      # < added the very important `..` by edit

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

git cherry-pick --no-merges ..A@{1}  # just learned now that cherry-pick takes this

关于git - 缺少 git 提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44937599/

相关文章:

ruby-on-rails - 如何更新 Gem 上的单个提交?

git/gerrit 防止 develop 分支 merge 到 stable/testing 分支

git - SmartGIT 不要求 ssh key

git - 软重置后返回最新提交

git bash : Can't spawn kdiff3 as difftool

Git 图不显示分支

git - .gitignore 的奇怪行为

Git stash pop 与二进制 - merge 冲突

git - 在 Git 中删除分支时究竟发生了什么

git - 查找删除分支的人?