自动重写开源版本的git历史记录

时间:2012-07-14 10:19:37

标签: git open-source release code-analysis revision-history

我目前正在发布几个项目作为开源。通常,完整的源代码以ZIP存档形式提供,或者在开源代码库中签入。这使得ohloh的分析变得困难。

如果软件是在非公共存储库中开发的,则可以获得完整的历史记录。但是,我不希望发布完整的历史记录。

我想使用git来达到两个可能性中的一个:

(i)每位作者一次提交: 每个作者应该有一个提交(提交日期是最终发布日期)。每个提交都包含代码行,最终使其成为最终版本。

(ii)仅包含最终代码行的原始提交:在此变体中,保留提交数量本身。每个提交的修改方式只保留最终成为最终版本的行,并删除所有其他行。

有没有人实现其中一个变种? Variant(i)似乎可以使用git-blame和一些脚本来实现。

2 个答案:

答案 0 :(得分:2)

(i)每位作者一次提交

我想这在逻辑上是不可能的:假设你有一系列这样的提交:

  • 承诺:A,作者:Alpha
  • 承诺:B,作者:Beta
  • 承诺:C,作者:Alpha

如果提交C取决于B中完成的任何事情,则无法再重新排序并压缩A和C.

(ii)仅提供最终代码行的原始提交

为此你可以使用'git filter-branch --tree-filter'。请注意以下脚本可能会吃小猫,因为我只在一个简单的测试库上测试过它。你被警告了:

git filter-branch --prune-empty --tree-filter '
    # directory which contains the final version of the project
    FINAL_VERSION="$DIRECTORY_WITH_REPOSITORY_OF_FINAL_VERSION"

    # directory which contains the filtered version of the repository
    FILTER_DIR="$(pwd)"

    # apply the current commit in to the final version in reverse mode,
    # ignore the rejects
    cd "$FINAL_VERSION"
    git show "$GIT_COMMIT" > /tmp/original.patch
    cat /tmp/original.patch | patch -p1 -t
    git diff > /tmp/filtered.patch

    # reset the FINAL_VERSION to the original state.
    git reset --hard
    git clean -f -d -x

    # apply the patch which contains the lines which could be reversed on
    # the filtered version
    cd "$FILTER_DIR"
    # revert the last commit
    patch -p1 -t < /tmp/original.patch

    # apply the filtered patch
    patch -p1 -t < /tmp/filtered.patch
    # remove the rejects by the modified patch 
    find -name "*.orig" -o -name "*.rej" | xargs rm -rf
' previousRelease..HEAD    

(这假设您已使用“previousRelease”标记了分支点。您还必须调整FINAL_VERSION变量。)

答案 1 :(得分:2)

git-oss-releaser是选项(i)的解决方案。

git-oss-releaser将给定的git存储库转换为仅包含上次提交文件的git存储库,并为每个文件提交类似git blame输出的提交。 原来的历史遗失了。

用法:git-oss-releaser.py [-h] repoDir outDir

位置参数:

  • repoDir:要转换的存储库。也可以是回购的子目录。
  • outDir:应创建新repo的目录。必须是空的。

可选参数:

  • --name NAME user.name用于提交文件。默认为git的全局user.name
  • --email EMAIL user.email用于提交文件。默认为git的全局user.email
  • --date DATE提交时使用的日期。默认为上次提交的日期。

请注意,git在提交时区分作者和提交者。 作者使用git blame,提交者数据来自全球user.nameuser.email或给定的已配置--name--email

目前只能在代码中启用DEBUG模式。

限制

  • 适用于没有任何未跟踪文件的git存储库
  • 空行分配给“git-oss-releaser”而不是添加这些空行的第一个或最后一个作者
  • 存储库必须至少包含一个非二进制文件
  • 提交日期仅来自非二进制文件
  • 仅在git for windows
  • 下测试
相关问题