代码之家  ›  专栏  ›  技术社区  ›  Adam Casey

使用git过滤器分支删除除文件列表之外的所有文件的历史记录

  •  5
  • Adam Casey  · 技术社区  · 8 年前

    repo1 repo2 。我有一个简短的文件列表,我想移动(保存历史)。

    报告1

    libraryname/file1
    libraryname/file2
    tests/libraryname/file3
    

    libraryname/ tests/libraryname/ / tests/

    我的计划是结帐 报告1 报告2 ,并合并到上一个操作的输出中。看起来像是 git filter-branch

    到目前为止我已经试过了 git filter-branch --index-filter 'git rm -r --cached <FILES>' 哪里 <FILES> 列出每个不需要的整个文件夹或文件。

    但这会留下许多文件夹,这些文件夹在 HEAD

    如何得到一个只包含这三个文件的git提交树? 有没有更好的办法? 或者,有没有办法删除当前不存在的所有文件的痕迹 ?

    3 回复  |  直到 8 年前
        1
  •  8
  •   Community Mohan Dere    5 年前

    Git 2.24(2019年第4季度), git filter-branch is deprecated

    等价物是,使用 newren/git-filter-repo ,及其 example section :

    如果您有一长串要过滤的文件、目录、全局或正则表达式,可以将它们粘贴到文件中并使用 --paths-from-file stuff-i-want.txt 内容为

    README.md
    guides/
    tools/releases
    glob:*.py
    regex:^.*/.*/[0-9]{4}-[0-9]{2}-[0-9]{2}.txt$
    tools/==>scripts/
    regex:(.*)/([^/]*)/([^/]*)\.text$==>\2/\1/\3.txt
    

    git filter-repo --paths-from-file stuff-i-want.txt
    

    就你而言, 将是:

    libraryname/file1
    libraryname/file2
    tests/libraryname/file3
    

    kubanczyk in the comments :

    在Ubuntu 20.04上运行良好,你可以 pip3 install git-filter-repo

    在Ubuntu 18上,它与发行版的git版本不兼容,但在一个 docker run -ti ubuntu:20.04

        2
  •  6
  •   Marc-André Lafortune    6 年前

    你说它会留下文件夹;我猜你的意思是它会留下文件 在里面

    git filter-branch ...
        --index-filter 'git rm -r --cached * && git reset $GIT_COMMIT -- libraryname/file1 libraryname/file2 tests/libraryname/file3
        ...
    

    由于您正在对内容进行细化,请不要忘记,您可能希望包含一个 --prune-empty 选项

        3
  •  1
  •   Guenther Brunthaler    8 年前

    这是一种基于白名单的方法,如果涉及大量文件,该方法可能更快(因为它只需要比较预排序列表的整行),也更容易。

    1. 创建分支所有提交中所有文件的排序列表:

      $ export LC_COLLATE=C whitelist="$(mktemp)" && git log --name-status | sed 's/^[A-Z][[:space:]]\{1,\}//; t; d' | sort -u > "$whitelist"

    2. 用你最喜欢的文本编辑器编辑该列表,删除所有不需要保留的文件,即创建一个要保留的文件的白名单。

      $ "$EDITOR" -- "$whitelist" # remove from list what you don't want to keep

    3. $ git filter-branch -f --index-filter 'git ls-files -c | sort | comm -23 -- - "$whitelist" | while IFS= read -r f; do git rm --cached -- "$f"; done' --prune-empty

    4. 一旦过滤器操作正常运行,请删除白名单。

      $ rm -- "$whitelist" && unset LC_COLLATE whitelist