【问题标题】:How do I enable shell options in git?如何在 git 中启用 shell 选项?
【发布时间】:2011-11-08 12:55:43
【问题描述】:

我想在 "index-filter" 中使用扩展通配符,例如

git filter-branch --index-filter "git rm --cached --ignore-unmatched Modules/!(ModuleA|ModuleB)"

但我得到一个错误:

eval:第 336 行:意外标记 `(' 附近的语法错误

我已经试过了:

git filter-branch --index-filter "shopt -s extglob && git rm --cached
--ignore-unmatched Modules/!(ModuleA|ModuleB)"

所以一般的问题是:如何为用于评估这些表达式的 shell 启用特定的 shell 选项?

【问题讨论】:

    标签: git git-filter-branch


    【解决方案1】:

    您可以通过让您的 shell 调用 git filter-branch 为您评估 glob 来规避该问题(假设您在那里启用了 extglob):

    git filter-branch --index-filter "git rm --cached --ignore-unmatch $(ls -xd Modules/!(ModuleA|ModuleB))"
    

    更新:您需要向ls 提供参数:-x 以空格而不是换行分隔条目,-d 以打印目录名称而不是其内容。对于多个文件,您可能还需要添加 -w 1000(或类似的大数字)以使 ls 假定一个非常宽的终端并将所有内容放在一行中。

    【讨论】:

    • 似乎不起作用。它找到 ls 输出的文件并在这些文件上抛出错误。
    • 我跑了git filter-branch --index-filter "git rm --cached --ignore-unmatch $(ls application/!(services|modules))"。每个与 $(ls ...) 命令不匹配的文件或目录都会出现错误消息。例如:“/usr/lib/git-core/git-filter-branch: 51: eval: scripts: not found”。 "scripts" 是 /application 中的一个目录。
    • 问题是由于某种原因$(ls ...) 按列而不是按行打印。我已经更新了我的答案。
    • @Bae 你是对的,如果文件数量超过几个,你会得到多行。但是,您可以添加 -w 1000(或其他一些较大的数字)以使 ls 假定一个非常宽的终端并将输出返回到单行。
    • 如果调用 git filter-branch 的 shell 执行 globbing,它会根据当前目录布局进行评估。我想通过对里面的目录结构进行大量更改来重写历史。它可以使用树过滤器而不是索引过滤器来解决,但这会慢很多倍,因为它会为每个修订版进行完整的检查。
    【解决方案2】:

    我知道这不是您所要求的,但仍然可以解决您的问题。我列出了不是docsresearch 的路径,然后将它们删除。

    PATHS_TO_REMOVE=$(git log --all --pretty=format: --name-only | sed 's@/.*@@' | sort | uniq | egrep -v '^docs$|^research$' | xargs)
    git filter-branch -f --index-filter "git rm -r --cached --ignore-unmatch $PATHS_TO_REMOVE" --tag-name-filter cat -- --all
    

    您应该能够对子目录执行类似的操作。

    【讨论】:

      猜你喜欢
      • 2017-07-30
      • 2013-09-14
      • 2010-12-11
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多