为什么 Git 知道它可以挑选一个已恢复的提交?

2024-03-08

比如说,在一个分支中有 3 个提交:A <- B <- C。如果我挑选B直接地 (Test A),Git 说:

The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

我能理解,因为B已经在这个分支中,无法再次挑选它。

然后我又恢复了B and C批量提交:

git revert -n B^..C
git commit -a -m "xxx"

这将是一个新的重大承诺D这会恢复B and C,分支应该是这样的A <- B <- C <- D.

然后我需要重做B and C由于某种原因。我试过:

git cherry-pick B^..C

我看到两个新提交B' and C'附加到分支:A <- B <- C <- D <- B' <- C'.

My 第一个问题是,Git 如何能聪明地知道它应该创造B' and C'?我以为 Git 会找到B and C已经在分支历史记录中,所以它可能会跳过它们,就像我直接在其中挑选“B”一样Test A.

然后,在那之后,由于分支已经A <- B <- C <- D <- B' <- C',我再次运行此命令:

git cherry-pick B^..C

我期望 Git 能够识别出这是一个无操作操作。但这一次 Git 抱怨冲突。我的第二个问题那为什么这次Git无法识别并跳过这个操作呢?


cherry-pick 是从你的cherry-pick 的父级到cherry-pick 的差异以及从你的cherry-pick 的父级到你的签出提示的差异的合并。就是这样。 Git 不需要知道更多的事情。它不关心任何提交在“哪里”,它关心合并这两组差异。

还原是还原到其父级的差异与还原到签出提示的差异的合并。就是这样。 Git 不需要再知道了。

在这里:试试这个:

git init test; cd $_
printf %s\\n 1 2 3 4 5 >file; git add .; git commit -m1
sed -si 2s,$,x, file; git commit -am2
sed -si 4s,$,x, file; git commit -am3

Run git diff :/1 :/2 and git diff :/1 :/3。这些是当你说时 git 运行的差异git cherry-pick :/2这里。第一个 diff 更改了第 2 行,第二个 commit 更改了第 2 行和第 4 行;第 4 行的更改不与第一个 diff 中的任何更改相邻,并且第 2 行的更改在两者中是相同的。一切都已无事可做:/1-:/2变化也在:/1-:/3.

现在,在您开始以下内容之前,让我这样说:用散文来解释这比仅仅看到更难。执行上面的示例序列并查看输出。这是much, much通过查看它比阅读任何描述更容易了解正在发生的情况。每个人都会经历一段时间,这太新了,也许一点指导会有所帮助,这就是下面段落的目的,但同样:散文本身比差异更难理解。运行差异,尝试理解您正在查看的内容,如果您需要一些帮助来解决我承诺的一个非常小的驼峰,请按照下面的文本进行操作。当它突然聚焦时,看看你是否至少在精神上拍拍你的额头并想“哇,为什么这么难看?”,就像,好吧,几乎每个人一样。

Git 的合并规则非常简单:对重叠或相邻行的相同更改将按原样接受。对已更改行的一个差异中没有更改的行的更改,或在另一行中与已更改行相邻的行,将按原样接受。不同的对任何重叠或邻接线的更改,嗯,有大量的历史需要查看,而且没有人找到一条规则可以预测每次的结果应该是什么,因此 git 声明更改冲突,转储两组结果进入文件并让您决定结果应该是什么。

那么如果现在更改第 3 行会发生什么呢?

sed -si 3s,$,x, file; git commit -amx

run git diff :/1 :/2 and git diff :/1 :/x,你会看到,相对于cherry-pick的父级,:/2更改了第 2 行,您的提示更改了第 2,3 和 4 行。2 和 3 相邻,从历史上看,这对于自动精灵来说太接近了,无法正确处理,所以是的,您可以这样做:git cherry-pick :/2现在将声明冲突,向您显示对第 2 行的更改以及第 3 行和第 4 行的两个不同版本(:/2 都没有更改,您的提示都更改了,在此处的上下文中,很明显第 3 行和第 4 行的更改很好,因为-再次强调:没有人想出一个自动规则来可靠地识别此类上下文)。

您可以对此设置进行更改以测试恢复的工作原理。还隐藏弹出、合并和git checkout -m它与您的索引运行快速临时合并。

Your git cherry-pick B^..C是两次提交的精选,B and C。它会一个接一个地执行这些操作,正如上面所描述的那样。既然你已经恢复了B and C,然后再次挑选它们,这与应用完全相同的效果B and C然后挑选樱桃B(目的是然后挑选C)。我的结论是B and C触摸重叠或邻接的线,所以git diff B^ B将显示与以下内容重叠或毗邻的变化git diff B^ C',这就是 Git 不会只为你选择的,因为无论这里看起来正确,在其他情况下没有人可以编写识别规则,看起来相同的选择将是错误的。所以 git 说两组更改发生冲突,你需要解决它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Git 知道它可以挑选一个已恢复的提交? 的相关文章

  • Git 无效的修订范围 Symfony2 Composer 外部包

    RuntimeException Failed to execute git log 18efcf67d236d5bbf46ac67820250dffd0474b6e 94e2146f525fa1367e15646fa273e5b34f92
  • 运行“git apply”时出错

    当我尝试时 您能否告诉我如何解决 补丁不适用 错误 git 应用补丁 git apply 0001 my patch error patch failed test xml 114 error text xml patch does not
  • Git:如何变基到特定提交?

    我想变基到特定的提交 而不是另一个分支的 HEAD A B C master D topic to A B C master D topic 代替 A B C master D topic 我怎样才能做到这一点 您可以通过在您喜欢的提交上创
  • 重新打包存储库对于大型二进制文件有用吗?

    我正在尝试将大量历史记录从 Perforce 转换为 Git 并且一个文件夹 现在是 git 分支 包含大量大型二进制文件 我的问题是运行时内存不足git gc aggressive 我的主要问题是重新打包存储库是否可能对大型二进制文件产生
  • SSH 到 Openshift 服务器失败

    我正在 openshift 服务器上使用 jboss catridge 我希望与其他人共享此实例并添加其他用户的公钥 id rsa pub 当其他人尝试访问该实例时 他会收到以下错误 我在他的实例中尝试了同样的方法 但看到了同样的错误 与
  • 分支明显不同,但提交历史是相同的

    git status告诉我我的分支和我在另一个存储库上开始的分支已经分歧 On branch master Your branch and origin master have diverged and have 13 and 13 dif
  • 如何使用交互式变基将提交编辑为未提交?

    我想使用交互式变基来编辑以前的提交 但是当我进入该提交的编辑模式时 所有文件都已提交 我知道我可以进行更改并修改提交 但我希望所有更改最初都未提交 暂存或以其他方式 这样我就可以对其进行编辑 就像在最初提交之前一样 这可能吗 Imagine
  • 如何从 android.googlesource.com 或 github.com 下载单个目录?

    我想下载 https android googlesource com platform frameworks base git master tools aapt https android googlesource com platfo
  • 远程测试时如何搭建git开发环境

    这似乎是一个愚蠢的问题 但我觉得我对 GIT 相当了解 但我似乎无法按照我的意愿设置我的开发环境 我要么错过了一些非常简单的东西 要么我做错了 我在我的服务器上初始化了一个裸 git 存储库 将其克隆到我的本地计算机 提交我的文件并推送到原
  • git pull,忽略深度,如何不拉取整个历史记录?

    我们有一个巨大的多 GB git 存储库 主要是二进制对象 克隆需要几天时间 实际的主分支 没有历史记录 只有大约 20MB 所以我想 深度为 1 的 git 克隆就是解决办法 然而 现在我需要将某人的更新拉到主服务器 我们没有分支 当我拉
  • Git:显示分支之间的差异,忽略合并的提交

    我的存储库历史记录看起来像这样 x y z branch a b c d e master 我想获得 branch 完整历史记录的单个差异 即 像 git diff 输出 我不想要像 git log p 产生的一大堆差异 而不包括任何从 m
  • git Push over sshfs 失败,并显示“关闭 sha1 文件时出错:错误的文件描述符”

    我们使用 sshfs 通过 SSH 安装文件系统 并将其用作 git 存储库协作的远程存储 Mac OSX 10 6 6 到 RHEL 3 服务器 SSHFS 版本 2 2 MacFUSE SSHFS 2 2 0 MacFUSE 库版本 F
  • Composer 用于下载私有 GitHub 存储库

    我无法使用 Composer 下载 github 私人存储库 php composer phar update 我收到以下错误 The https api github com repos company private1 https ap
  • 致命:.git/info/refs 无效:这是一个 git 存储库吗?

    我有一个托管在 Assembla 上的 Git 存储库 我正在尝试执行以下操作 git push u origin master 我一遍又一遍地收到以下错误 fatal https url repo name git info refs n
  • .gitconfig 别名函数调用

    我在 gitconfig 中定义了以下别名 alias teamcity tc tc是我在我的中定义的一个shell函数 bashrc文件 由于某种原因 我收到以下错误 aafghani 03 git workday amirafghani
  • `git Reset HEAD file` 是否也检查该文件?

    我错误地向 git 添加了一个目录 当我按照提示操作时here https stackoverflow com questions 348170 undo git add通过执行以下操作来撤消添加git reset HEAD
  • 如何在 macOS 上将 Git 升级到最新版本?

    我刚刚购买了一台装有 OS X Lion 的新 Mac 我在终端中检查了默认安装的 git 版本 我得到了答案 git version gt git version 1 7 5 4 我想将 git 升级到最新版本 1 7 8 3 因此我下载
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • 如何使用 Git 跟踪目录而不是文件?

    我最近开始使用 Git 但只有一件事遇到了麻烦 如何在不跟踪目录内容的情况下跟踪目录 例如 我正在开发的网站允许上传 我想跟踪上传目录 以便在分支等时创建它 但显然不是其中的文件 在开发分支中的测试文件或主控中的真实文件 在我的 gitig
  • 无法通过 Git Bash 克隆 git 存储库

    在尝试使用克隆存储库时git clone 它显示以下错误 致命 无法访问 https github com microsoft c9 python getting started git https github com microsoft

随机推荐