【问题标题】:Keep git history when splitting a file拆分文件时保留 git 历史记录
【发布时间】:2011-04-22 17:04:21
【问题描述】:

我想从一个文件中取出一个函数并将其放入另一个文件中,但保留责备历史记录。

cp a.php b.php

vim b.php
# delete everything but 1 function

vim a.php
# delete the 1 function

git add a.php b.php
git commit

但如果我运行 git blame b.php 我只会看到它归咎于这个新提交。

【问题讨论】:

    标签: git history git-svn


    【解决方案1】:

    维护责备历史的一般规则是在进行任何编辑之前先进行单独的 move 提交。根据我的经验,这允许git blame 无需-C 选项即可工作。因此,在将文件拆分为新文件的情况下,这可以在两次提交中完成:

    1. 将原件复制到新目的地,确保删除原件
    2. 从重复文件中删除多余的部分

    在提供的示例中,这将是:

    cp a.php b.php
    mv a.php c.php
    git add a.php b.php c.php
    git commit
    vim b.php  # delete everything but 1 function
    vim c.php  # delete the 1 function
    git add b.php c.php
    git commit
    

    【讨论】:

    • git add 在不存在的文件上的行为在 Git 1.9 左右发生了变化。您需要 git rmgit add -A 来反映已删除的文件。
    • 感谢@DamianYerrick 的评论。我不认为如果您指定要暂存的确切文件,这两种方式都不重要。 (变化在于,从 git 2.0 开始,“git add <path>git add -A <path> 相同,因为它包括根据 release notes 的删除)。
    【解决方案2】:

    我稍微修改了Peter's answer to another question here 以创建一个名为git-split.sh 的可重用、非交互式shell 脚本:

    #!/bin/sh
    
    if [[ $# -ne 2 ]] ; then
      echo "Usage: git-split.sh original copy"
      exit 0
    fi
    
    git mv $1 $2
    git commit -n -m "Split history $1 to $2"
    REV=`git rev-parse HEAD`
    git reset --hard HEAD^
    git mv $1 temp
    git commit -n -m "Split history $1 to $2"
    git merge $REV
    git commit -a -n -m "Split history $1 to $2"
    git mv temp $1
    git commit -n -m "Split history $1 to $2"
    

    它只是将源文件复制到一个新文件中,并且两个文件具有相同的历史记录。在that other answer

    中可以看到为什么这个工作的解释

    【讨论】:

      【解决方案3】:

      也许这个先前的 SO 问题可能会提供信息:

      How does git track source code moved between files?

      套用公认的答案:本质上,Git 并没有“存储”移动的代码;当生成诸如移动代码的责备之类的东西时,这是通过检查整个存储库从提交到提交的状态事后完成的。

      【讨论】:

      • 这个答案听起来像是“不”,但实际上是“有时”。删除似乎是触发 Git 查看文件以获取其他文件出生日期之外的历史记录的原因。拆分一个函数但像 OP 一样保留文件的其余部分可能不起作用。但是我只是将一个文件一分为二,删除了原来的文件,并给它起了两个新的名称,并且在两个新文件中都正确分配了责任。
      • 糟糕,那只是在编辑之后。在提交后,它显然失去了对其中一个新文件的责任。还是有可能?
      • @Potatoswatter 尝试将每个文件拆分到单独的分支中,然后合并分支。我认为这应该让 git 识别“多个副本”。
      【解决方案4】:

      试试git blame -C -C b.php

      【讨论】:

      • 我希望历史真正归咎于较旧的提交。我们使用 git-svn,所以其他人会使用 svn。
      • 太糟糕了。 SVN 根本不支持这个!
      • 超级有用,tx.. 还没找到git log 的解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多