繁体   English   中英

重写git历史记录以使crlf保持一致

[英]Rewriting git history to make crlf consistent

我有一个git存储库,具有LF和CRLF文件的精细变体。

在进行可能的切换之前,我想重写提交,其中父级和当前提交具有​​不同的LR / CRLF编码。

所以我尝试了下面的“one-liner”(稍加编辑),如果文件的父版本包含CR,我会尝试运行todos

$ git filter-branch --tree-filter '
  echo
  P=$GIT_COMMIT^;
  FILES=$(git diff --name-only $P);
  for a in $FILES; do
     if ! git cat-file -e $P:$a; then echo "no parent"; continue; fi;
     if git show $:$a | grep -qUP '\r'; then
        echo "parent is dos";
        todos $a;
     else
        echo "parent is unix";
        fromdos $a;
     fi;
  done' 23498f..HEAD

它不起作用。 任何人都可以发现错误或解决这个问题吗?

我在回答我自己的问题。 我原来的解决方案中的错误是FILES集是错误的,因为在重写的父级和当前提交之间没有获取diff,而是在原始父级和当前提交之间。

遍历这样的一组提交时,需要更改的文件不是提交所触及的文件集,而是一些父提交弄乱了行结尾的文件集。

这意味着我没有获得正确的文件集。 为filter-branch表达式提供了一个map函数,可以将“原始”rev转换为重写的rev。 当我使用该功能时,它可以正常工作。

由此产生的“单线”看起来像这样:

$ git filter-branch -f --tree-filter '                         
    echo "\n $GIT_COMMIT";
    P=$(git rev-parse $GIT_COMMIT^);
    echo $P;
    P=$(map $P);
    echo $P;
    git cat-file commit $GIT_COMMIT;
    FILES=$(git diff --name-only $GIT_COMMIT $P);
    echo "FILES:\n$FILES"; 
    for a in $FILES; do
        git cat-file -e $P:$a > /dev/null 2>&1 || continue;
        if git show $P:$a | grep -qUP '\r'; then
           echo "parent is dos $a";
           todos $a;
        else
           echo "parent is unix $a";
           fromdos $a;
        fi;
    done;
    git add $FILES;' a6d9e..HEAD 

大多数aI不认为需要最后一个'git add $ FILES',但这是我使用的命令,我不想提供错误的答案。

注意:还应该可以定义FILES=$(git diff --name-only a6d9e HEAD) ,因此在遍历提交时使用固定集。 这可能更简单,但我没有这样做。

你真的想重写历史吗?

使用内置配置选项有助于使这些事情透明化。 我已经做了类似的事情,在过去的几年里,与Windows,Mac和Linux系统上的人一起工作尚未遇到行结尾的问题。

看看GitHub 处理线路结尾

以下是他们对配置文件的看法:

这是一个示例.gitattributes文件,您可以将其用作所有存储库的模板:

# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto

# Explicitly declare text files we want to always be normalized and converted 
# to native line endings on checkout.
*.c text
*.h text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary The advantage of this is that your end of line configuration now travels with your repository and you don't need to worry about whether or not collaborators have the proper global settings.

如果您有一个当前的存储库,他们会继续讨论您可以做什么,并且需要将这些设置应用于它。

重新规范存储库

在设置core.autocrlf选项并提交.gitattributes文件之后,您可能会发现git想要提交您未修改的文件。 这是因为git想要为你的行结尾标准化。 执行此操作的最佳方法是清除工作树(除.git目录之外的所有文件),然后还原它们。 确保在执行此操作之前已经完成了任何工作,否则它将丢失。

git rm --cached -r .
# Remove everything from the index.

git reset --hard
# Write both the index and working directory from git's database.

git add .
# Prepare to make a commit by staging all the files that will get normalized.
# This is your chance to inspect which files were never normalized. You should
# get lots of messages like: "warning: CRLF will be replaced by LF in file."

git commit -m "Normalize line endings"
# Commit

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM