【问题标题】:Fixing "patch does not apply" when editing a hunk from git add -p从 git add -p 编辑大块时修复“补丁不适用”
【发布时间】:2014-05-10 13:06:24
【问题描述】:

我对代码文件进行了一系列更改,并在暂存之前执行git add -p path/to/file.hpp 检查差异。

总结一下我的更改:我已将常规类声明转换为模板类定义。在这样做的过程中,我从文件底部取出一大块代码并将其移到顶部(现在需要在类之前定义一个异常类),然后我替换了一堆-liners(方法声明),每个都有几行代码(方法实现)。

Git 无法正确检测到我的更改的上下文,并且基本上已经在一个大杂烩中删除和添加了行,其中两条相邻的行之间根本没有任何联系差异。为了使更改更易于稍后检查,我转移了一堆更改以使它们在上下文中,但小心地保持所有添加和删除的行以相同的顺序,保持添加和删除的行数不变等等.

完成后,我收到错误消息

error: patch failed: include/aof/physics/magnetic-field.hpp:143
error: include/aof/physics/magnetic-field.hpp: patch does not apply
Your edited hunk does not apply. Edit again (saying "no" discards!) [y/n]? 

好的,所以我在某个地方犯了一个错误。好的,我会再试一次。再次发送相同的消息。

如果我在上面回答y,我可以回到我编辑的补丁,但是因为我不知道它有什么问题,所以对我没有多大帮助。在尝试多次编辑补丁失败后,我不禁想知道:有没有办法在这里获得更好的错误消息?我如何找出为什么补丁不适用,所以我可以修复它?

简化示例以阐明我要完成的工作

原始补丁。不太容易看到这里发生了什么......

-        ClassConstructor(const OtherClass& other, double d);
+        ClassConstructor(const TOtherClass& other, double d) : _other(other), _d(d) {

-        void method1() const;
-        double calculation() const;
-        double otherCalculation() const;
+            _a = 1 / d;
+        }

-        ~ClassDestructor() { }; // Yes, of course it's more sensibly named
-     };
+        void method1() const {
+             // this method does nifty stuff.

-    struct my_exception_type : public std::runtime_error {
-        my_execption_type() : runtime_error("oops!") {
         }

-        virtual const char* what() const throw() {
-            std::ostringstream cnvt;
-            cnvt << runtime_error::what() ": Sorry, I shouldn't have done this...";
+        double calculation() const {
+            return _a + _d;
+        }

-            return cnvt.str().c_str();
+        double otherCalculation() const {
+            return 0.; // I'm lazy
         }

+        ~ClassDestructor() { }; // Yes, of course it's more sensibly named
     };

我尝试将其编辑为的内容。 (此编辑在 SO 完成,因此不确定这个特定的是否有问题,但您知道我正在对大块进行什么样的编辑)。更容易理解这些变化,你不觉得吗?

-        ClassConstructor(const OtherClass& other, double d);
+        ClassConstructor(const TOtherClass& other, double d) : _other(other), _d(d) {
+            _a = 1 / d;
+        }

-        void method1() const;
+        void method1() const {
+             // this method does nifty stuff.
+        }

-        double calculation() const;
+        double calculation() const {
+            return _a + _d;
+        }

-        double otherCalculation() const;
+        double otherCalculation() const {
+            return 0.; // I'm lazy
+        }
     };
-    struct my_exception_type : public std::runtime_error {
-        my_execption_type() : runtime_error("oops!") {
-        }
-        virtual const char* what() const throw() {
-            std::ostringstream cnvt;
-            cnvt << runtime_error::what() ": Sorry, I shouldn't have done this...";
-            return cnvt.str().c_str();
-    };

显然,在正确的空行数等方面存在很大的出错风险,但我的问题不仅在于很难确保它全部正确 - 也很难弄清楚我犯了什么错误.

【问题讨论】:

  • 这个问题有帮助吗:stackoverflow.com/questions/3268596/… ?
  • @LeGEC:这个问题在故障排除方面提供了有用的指导,但它并没有真正让我比我目前拥有的更多。这些信息对我来说都不是全新的,也不是我当前的补丁所特有的(无论当前的补丁是什么)。这个问题是,如果有办法从git 本身中挤出更多信息的错误消息。
  • 我不确定我是否完全理解您想要实现的目标。您是否正在尝试编辑补丁,以便 git 记住“第 1 行”实际上是“第 13 行”的替代品,“第 2 行”实际上是“第 26 行”的替代品,等等...?
  • @LeGEC:我做了一个简化的例子,它与实际案例非常接近。我希望它能澄清事情。

标签: git patch


【解决方案1】:

您不能使用git add -p 告诉 git “保留此补丁作为此文件两个版本之间差异的跟踪”:git 确实 存储差异或补丁,它存储实际 内容。

当您在 git (git add myfile) 中添加文件时,该文件的特定版本将收到基于其唯一 内容 的哈希值。 Git 将不跟踪它是如何从版本 n-1 到版本 n。

当你运行git diff时,git实际上会检索文件的两个版本的内容,并再次运行diff算法。您尝试编辑的补丁不会保存在内存中。


我能想到的最接近的方法是为 diff 算法本身添加“同步点”:

1- 从文件的第一个版本开始,在每个“迁移块”上提交带有 cmets 的第一个中间版本:

// migrating method1 :
void medthod1() const;

//migrating calculation :
void calculation() const;

//etc ...

2- 在第一次提交之后,写下你的实际迁移,保留 cmets:

// migrating method1 :
void method1() const {
    //this method does nifty stuff
}

// migrating calculation :
void calculation() const {
    return _a + _d;
}

//etc ...

并提交此版本。

3- 最后,删除不需要的、嘈杂的 cmets,并提交最后一个版本。

在浏览 git 历史时,迁移将显示为 3 次提交,在检查提交 2- 引起的差异时,您应该清楚地了解重写的内容。

【讨论】:

  • 好的。因此,无论如何,我试图完成的基本上是毫无意义的。好吧,感谢您对原因进行了很好的解释!
  • 你也可以改变 git 的 diff 算法,例如--patience,在这种情况下通常会提供更好的结果。
猜你喜欢
  • 2020-10-22
  • 2012-03-19
  • 2015-05-21
  • 2011-03-17
  • 2011-06-13
  • 2018-06-29
  • 2021-11-03
  • 2016-08-02
  • 1970-01-01
相关资源
最近更新 更多