【问题标题】:Git rm several files?git rm 几个文件?
【发布时间】:2012-03-20 17:21:53
【问题描述】:

如何轻松删除多个文件,而无需手动将所有文件的完整路径输入到git rm?我有很多修改过的文件要保留,因此也无法删除所有修改过的文件。

还可以在不手动输入git checkout -- /path/to/file的情况下恢复多个文件的更改?

【问题讨论】:

    标签: git git-rm


    【解决方案1】:

    在 POSIX 系统上,您可以创建一个与所有所需文件匹配的 shell glob,您只需将其传递给 git rmgit checkout --。在 Windows 上,cmd.exe 和 PowerShell 不包括通配符并将其分配给应用程序(根据我的阅读,git 不会为文件执行此操作)。您需要使用 Windows 命令或脚本来准备文件列表并将其适当地通过管道传递给您的 git 命令以获得类似的效果。

    将文件列表传递给 shell 命令的任何策略都适用于接受文件路径的 git 命令。

    【讨论】:

    • 哦,Windows 的 cmd.exe 和 PowerShell 不执行 globbing,据我所知,Windows 的 git 不包含此功能,因为它会破坏树/分支/提交 globbing(左右我读了)。您将不得不探索 Windows 的 shell 方法来匹配文件路径。
    【解决方案2】:

    只需使用任何其他方法(Explorer 等)删除它们,然后运行git add -A。至于还原多个文件,您也可以签出一个目录。

    【讨论】:

    • 此页面上最简单的方法。
    • 我来这里是为了寻找比 explorer 更简单的方法。如果我可以在 bash 中使用递归搜索找到我想要删除的所有文件,我宁愿不必在资源管理器中执行此操作并返回 git bash 来完成它。像这样的 almost 作品 find 。 -name "debug" -exec bash -c 'file={}; git rm $文件'\;它只是使用相对路径
    • 小心使用 -A 参数。 “如果使用 -A 选项时没有给出 ,则整个工作树中的所有文件都会更新(旧版本的 Git 用于将更新限制在当前目录及其子目录)”使用 -A 参数,您可能会进行您尚未准备好进行的更改
    【解决方案3】:

    您可以为git rm 提供通配符。

    例如

    git rm *.c
    

    或者你可以在另一个文件中写下所有文件的名称,比如filesToRemove.txt

    path/to/file.c
    path/to/another/file2.c
    path/to/some/other/file3.c
    

    您可以自动执行此操作:

    find . -name '*.c' > filesToRemove.txt
    

    打开文件并查看名称(以确保一切正常)。

    然后:

    cat filesToRemove.txt | xargs git rm
    

    或者:

    for i in `cat filesToRemove.txt`; do git rm $i; done
    

    查看xargs 的手册页以获取更多选项(尤其是文件太多时)。

    【讨论】:

    • 他在 Windows 上并使用 Windows 的 shell。
    • 这对于大约需要 3 秒的事情来说太复杂了。
    • 基本上它是“git rm ...”,你必须以某种方式传递所有文件名。没有 git 读心,这是最快的方法。
    • 请注意git rm *.c 似乎是递归的。
    • 使用git ls-files而不是find通常会更好,因为find可能会出现git尚未跟踪的文件并导致管道失败
    【解决方案4】:

    您还可以查看Cygwin,因为它在 Windows 上提供了许多 Unix/Linux/*BSD 功能。 Cygwin 包括一个 Bash shell 和 find(1),以及上面提到的其他工具。 (我通常在 Windows 7 上一次启动 2-4 个 Cygwin mintty 终端,因为我觉得 Cygwin 很方便。)

    【讨论】:

      【解决方案5】:

      要一次删除多个文件,您可能需要查看答案here

      您可以删除不需要的文件并运行此命令:git rm $(git ls-files --deleted)

      【讨论】:

        【解决方案6】:

        你可以简单地使用:

        git add -u
        

        来自官方documentation

        -u --更新

        在已经有条目匹配的地方更新索引 .这将删除并修改索引条目以匹配 工作树,但不添加新文件。

        如果使用 -u 选项时没有给出,所有跟踪的文件在 整个工作树都更新了(旧版本的 Git 用于限制 当前目录及其子目录的更新)。

        换句话说,来自这个answer

        它将更新或从整个工作树中删除以前跟踪的文件。它不会添加新文件。

        【讨论】:

        • 请在您的答案中添加更多详细信息。
        【解决方案7】:

        我发现git rm 对通配符的处理很烦人。 Find 可以在一行中完成: find . -name '*.c' -exec git rm {} \; {} 是文件名将被替换的地方。 find 的优点在于它可以过滤大量文件属性,而不仅仅是名称。

        【讨论】:

          【解决方案8】:

          在 Windows 10 上,使用 Git Bash,从文件结构中的 .gitignore 位置。

          git rm -r --cached some_directory/
          

          我只是用它来递归地忽略整个目录。 这就是我的.gitignore 文件中的内容:

          # Use .gitignore to ignore a directory and its contents #
          /some_directory/ 
          

          【讨论】:

            【解决方案9】:

            你只需使用

            find . -name '*.DS_Store' | xargs git rm
            

            要删除许多匹配通配符的文件。

            【讨论】:

              【解决方案10】:

              或者你可以在另一个文件中写下所有文件的名称,比如filesToRemove.txt

              这是使用 Git 2.26(2020 年第二季度)的好方法,因为“git rm”和“git stash”学习了新的“--pathspec-from-file”选项。

              所以没有更多的for i incat filesToRemove.txt; do git rm $i; done

              一个简单的git rm --pathspec-from-file=filesToRemove.txt 就足够了。

              参见commit 8a98758commit 8c3713ccommit 3f3d806commit b229091commit 0093abccommit 2b7460dcommit 5f393dc(2020 年 2 月 17 日)和commit 6a7aca6(2020 年 1 月 16 日)@9876 .
              (由 Junio C Hamano -- gitster -- 合并于 commit 9b7f726,2020 年 3 月 9 日)

              rm: 支持 --pathspec-from-file 选项

              签字人:Alexandr Miloslavskiy

              为简单起见做出的决定:

              args 和 file 中都不允许传递 pathspec。

              if (!argc) 块需要调整:

              此代码实际上意味着“路径规范不存在”。
              以前,pathspec 只能来自命令行参数,因此测试 argc 是测试 pathspec 是否存在的有效方法。但--pathspec-from-file 不再适用。

              在整个--pathspec-from-file 的故事中,我试图让它的行为非常接近于在命令行上给出路径规范,这样从一个切换到另一个不会有任何意外。

              但是,在--pathspec-from-file 为空的情况下向用户抛出用法会令人困惑,因为“用法”(即 argc/argv 数组)没有任何问题。

              另一方面,在旧案例中抛出用法也让我感觉不好。虽然这不是一个难题,但我(作为用户)从不喜欢将我的命令行与“用法”进行比较的体验,试图找出不同之处。由于已经知道错误是什么,因此将特定错误提供给用户感觉要好得多。

              从提交 7612a1ef ("git-rm:honor -n flag" 2006-06-09, git v1.4.0) 来看,在这种情况下显示使用似乎并不重要(补丁是以避免段错误),并且它不适合其他命令对空路径规范的反应(例如,请参见带有自定义消息的git add)。

              因此,我决定在这两种情况下都显示新的错误文本。
              为了尽早继续测试错误,我将parse_pathspec() 移到了更高的位置。现在它发生在read_cache() / hold_locked_index() / setup_work_tree() 之前,应该不会引起任何问题。

              【讨论】:

                【解决方案11】:

                简单的方法:

                • 在文件资源管理器中删除文件
                • 使用git ls-files --deleted | xargs git add 暂存它们。推送后,它们将在遥控器中删除。

                Git 方式: 参考@CpILL 所说的(https://stackoverflow.com/a/34889424/6538751)使用

                • find . -name 'DeleteMe*.cs' -exec git rm {} \;

                您可以使用通配符。

                【讨论】:

                  猜你喜欢
                  • 2012-09-06
                  • 2023-03-16
                  • 2015-08-05
                  • 2023-03-09
                  • 1970-01-01
                  • 2018-12-30
                  • 1970-01-01
                  • 2012-09-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多