【问题标题】:Best place/phase to resolve '^M' or '\r' character line ending解决 '^M' 或 '\r' 字符行结尾的最佳位置/阶段
【发布时间】:2019-03-24 01:11:43
【问题描述】:

我需要通过用更新的值替换消息代码来重构文件。我的原始文件存在于 Ubuntu 服务器中,我可以将其作为 Windows 文件进行挂载和访问。我在 Ubuntu Server 中通过 git 克隆它,然后将文件移动到 Windows 和 Windows 中,借助小型 Java 程序重构值并编写它。然后在 Windows 中打开文件,然后将要复制的文件粘贴到 Ubuntu 服务器中(因为复制替换或移动文件的替换显示 git diff,因为所有内容都已更改)。

以下是我用来进行重构的 Java 代码。

        ruleInBR = new BufferedReader(new FileReader(ruleIn));
        ruleOutBW = new BufferedWriter(new FileWriter(ruleOut));
        csvOutBW = new BufferedWriter(new FileWriter(csvOut));

        String readRule = "";
        int lineNo = 1;

        while((readRule = ruleInBR.readLine()) != null)
        {
            if(details.get(lineNo) != null)
            {
                AlterValuePair<String> avPair = details.get(lineNo);
                String renamedRule = readRule.replace(avPair.getOldValue(),avPair.getNewValue());
                String trimRenamedRule = renamedRule.replace("\r","");
                csvOutBW.write(lineNo + ", " + avPair.getOldValue() + ", " + avPair.getNewValue() +"\n");
                ruleOutBW.write(trimRenamedRule + "\n");
                count++;
            }
            else {
                String trimReadRule = readRule.replace("\r","");
                ruleOutBW.write(trimReadRule +"\n");

            }
            lineNo++;
        }

但在 GitDiff 中,我遇到了 git diff for '^M' 或 '\r' 存在的问题,我实际上没有这样做,据我所知,我知道这是因为我已经打开并与一些编辑器一起工作离开那些行结束。由于文件重构会由于意外字符而在 Ubuntu 中编译时导致问题。我遵循了我之前学习并在 Stack Overflow 中找到的以下方法。

我在 vim 中调整了以下选择

  1. set ff=unix /set fileformat=unix
  2. set ff=dos /set fileformat=dos
  3. %s/\r\n/\n/ 或 %s/\r// 或 %s/\r//g
  4. dos2unix 文件名
  5. perl -pi -e 's/\r//' 或 perl -pi -e 's/\r\n/\n/'

但所有这些情况都将 整个文件 更改为新文件,并且在 git diff 中显示所有更改都是新更改,而我没有更改的旧更改已更改。 有没有办法解决这个问题?

我已经从 Stack Overflow 解决了以下问题:

  1. gVim showing carriage return (^M) even when file mode is explicitly DOS
  2. Convert DOS line endings to Linux line endings in vim
  3. ^M at the end of every line in vim
  4. Remove a line in text file with java.BufferedReader
  5. https://its.ucsc.edu/unix-timeshare/tutorials/clean-ctrl-m.html
  6. https://www.garron.me/en/bits/get-rid-m-characters-vim.html

但他们都没有以积极的方式帮助我。

更新

最后,在遵循另一个 Stack Overflow 问题的说明后,该问题谈到在提交级别中省略,这将跳过添加空格并解决了我的问题,但这也有一些缺陷,因为它具有相同文件的某些部分未提交的(实际上属于空格中省略的)。

我实际上不知道如何处理这个问题,因为我必须对几个分支进行更改,所有这些可能会或可能不会遇到这个问题。有没有比在 git commit 级别做更简单的方法。每次我这样提交时,我都必须忽略空白并提交和存储未提交的更改。

顺便说一句,这个 Stack Overflow 链接:Add only non-whitespace changes

【问题讨论】:

  • 请准确说明你做了什么。如果我理解正确:1)在 Unix 上签出文件,2)复制到 Windows,3)运行 Java 文件以更改一些值,4)将转换后的文件复制回 Unix,5)提交文件。这是对您的时间线的正确描述吗?还是您没有提交,只是查看了与上次提交的差异?
  • 我也提交了,检查我是否更新了描述
  • readLine 不会读取 CR 字符,为什么要在 java 中这样做?

标签: java git vim


【解决方案1】:

因此,您的时间表,正如 cmets 中所确认的,以及正在发生的事情:

1) 在 Unix 上签出文件。该文件具有 Unix 行尾 (LF)。

2) 复制到 Windows。该文件仍然具有 Unix 行结尾。

3) 运行 Java 文件以更改一些值。当您阅读该文件时,您尝试从中删除 CR,即使它首先不包含 CR(仅 LF);但即使它确实包含 CR,它也不会起作用,因为根据 BufferedReader.readLine 文档,您会得到没有行尾的字符串。您使用\n 将行写入新文件; Java 将\n 理解为“行尾终止符”,这使得Java-on-Windows 在每一行写入Windows 行尾(CR LF)(在if 的两个分支中 - 即在更改的行和那些你只是打算复制而不改变的)。该文件现在的所有行都包含 Windows (CR LF) 结尾。

4) 将转换后的文件复制回 Unix。行尾是 Windows (CR LF)。

5) 提交文件。由于您在 Linux 上提交了文件,我假设 git 没有设置为在提交期间删除它们。因此,文件随着每一行的变化而被提交:一些行实质上,但一些行微不足道(只是行终止符的变化)。

现在,如果您尝试恢复 Unix 行终止符,您实际上是在更改整个文件 - 因为每一行都需要更改,即使只是一点点。

其他选项:

如果您已经推送了更改,显而易见的方法是 git revert 这个提交(这看起来也像更改整个文件,但至少很明显这是一个还原),然后要么重新运行 Java程序在 Unix 机器上,或者在复制回 Unix 机器之后但在提交之前执行dos2unix file

如果您尚未推送更改,则可以使用git reset --hard HEAD^ 而不是还原。

【讨论】:

  • 请阅读完整的答案,不要专注于关键字。当然,它会更改整个文件,因为整个文件是 Windows-dirty - 并且是在那个时候提交的。你犯下的事实就是问题所在。在历史记录中您没有更改整个文件的唯一情况是reset 选项,但它有点核 - 如果您的合作者已经撤消了您的更改,则很危险。除了重写历史记录之外,没有其他方法可以不更改历史记录中的每一行 - 因为您通过该提交将其放入历史记录。
  • dos2unix 的关键点在于,如果您在提交之前这样做,它就会起作用。它会剥离 CR LF 并将 LF 放回原处,这会将没有大量编辑的行恢复到 Windows Java 接触它们之前的状态。如果您设法撤消提交,然后 dos2unix 并提交,则该提交只会将具有实际更改的行作为更改的行。
  • 我已经完成了你的回答......顺便说一句,我从头开始尝试了大约 2 到 3 天的所有方法,最后我来在 stackoverflow 中询问我实际上搞砸了什么......
  • 正如我所说,您在提交脏文件时搞砸了。您现在的选择:重写历史记录以再次正确重做,或者接受所有已更改的行(然后再次更改以消除 Windows 污点)。
  • 我猜这个选项效果很好,而不是上面的策略,stackoverflow.com/questions/3515597/…
猜你喜欢
  • 2010-09-09
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多