【问题标题】:Remove directory from remote repository after adding them to .gitignore将目录添加到 .gitignore 后从远程存储库中删除目录
【发布时间】:2011-12-17 03:41:21
【问题描述】:

我提交了一些目录并将其推送到 github。之后,我更改了.gitignore 文件,添加了一个应该被忽略的目录。一切正常,但(现在被忽略的)目录保留在 github 上。

如何从 github 和存储库历史记录中删除该目录?

【问题讨论】:

标签: git github gitignore


【解决方案1】:

如果您在 Windows 机器上使用 Blundell 描述的技术(删除 everything 然后添加 everything),您可能会遇到所有文件都被修改的问题,因为行尾改变。为避免这种情况,请使用以下命令:

git rm -r --cached .
git config --global core.autocrlf false
git add --renormalize .
git add .

这会从索引中删除 所有 文件,将 git 配置为不更改行尾,重新规范行尾并暂存您刚刚删除的所有文件除了在 @ 中指定的文件987654323@

然后 git commit

参考:How to remove files from repository listed in .gitignore without changing whitespace

【讨论】:

    【解决方案2】:

    此方法应用标准的 .gitignore 行为,不需要手动指定需要忽略的文件

    不能再使用--exclude-from=.gitignore:/ - 这是更新后的方法:

    一般建议:从干净的 repo 开始 - 所有内容都已提交,工作目录或索引中没有任何待处理的内容,并进行备份

    #commit up-to-date .gitignore (if not already existing)
    #this command must be run on each branch
    git add .gitignore
    git commit -m "Create .gitignore"
    
    #apply standard git ignore behavior only to current index, not working directory (--cached)
    #if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
    #this command must be run on each branch
    git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
    
    #optionally add anything to the index that was previously ignored but now shouldn't be:
    git add *
    
    #commit again
    #optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.
    
    git commit -m "re-applied modified .gitignore"
    
    #other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED
    

    如果您还需要从分支的提交历史记录中清除新忽略的文件或者如果您不希望从未来的拉取中删除新忽略的文件,请参阅this answer

    【讨论】:

      【解决方案3】:

      Blundell 的回答应该有效,但出于某种奇怪的原因,它对我没有用。我必须先将第一个命令输出的文件名通过管道传输到一个文件中,然后遍历该文件并逐个删除该文件。

      git ls-files -i --exclude-from=.gitignore > to_remove.txt
      while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
      rm to_remove.txt
      git commit -m 'Removed all files that are in the .gitignore' 
      git push origin master
      

      【讨论】:

        【解决方案4】:

        Blundell 的第一个答案对我不起作用。然而,它向我展示了正确的方式。我也做过这样的事情:

        > for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
        > git commit -m 'Removed all files that are in the .gitignore'
        > git push origin master
        

        我建议您首先通过运行以下语句检查要删除的文件:

        git ls-files -i --exclude-from=.gitignore
        

        我正在为 Visual Studio 使用默认的 .gitignore 文件,我注意到它正在删除项目中的所有日志和 bin 文件夹,这不是我的预期操作。

        【讨论】:

        • 如果您使用的是 windows powershell,请使用 "foreach ($i in git ls-files -i --exclude-from=.gitignore) {git rm --cached $i;}" 不带引号.
        【解决方案5】:

        注意:此解决方案仅适用于 Github Desktop GUI

        使用Github Desktop GUI非常简单。

        1. 暂时将文件夹移动到另一个位置(移出项目文件夹)。

        2. 编辑您的 .gitignore 文件并删除文件夹条目,该条目将在 github 页面上删除主存储库。

        3. 提交并同步项目文件夹。

        4. 将该文件夹重新移动到项目文件夹中

        5. 重新编辑.gitignore文件。

        就是这样。

        【讨论】:

          【解决方案6】:

          如果您使用 PowerShell,请将以下命令作为单个命令尝试。

          PS MyRepo> git filter-branch --force --index-filter
          >> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
          >> --prune-empty --tag-name-filter cat -- --all
          

          那么,git push --force --all

          文档:https://git-scm.com/docs/git-filter-branch

          【讨论】:

          • 使用git filter-branch 与使用git rm 有何不同?我原本以为我必须使用 git filter-branch 的版本,但这里的大多数 cmets 建议使用 git rm。据我了解git rm 仅将其从当前工作目录和索引中删除。但是如果它之前添加了多个提交,它仍然会在存储库中。
          • 对。 git rm 将把文件从最新的提交中删除到未来。 git filter-branch 让我们将其从整个历史记录中删除。另见:help.github.com/articles/…
          【解决方案7】:

          根据我的回答:How to remove a directory from git repository?

          要仅从 git 存储库而不是从本地删除文件夹/目录,请尝试 3 个简单步骤。


          删除目录的步骤

          git rm -r --cached FolderName
          git commit -m "Removed folder from repository"
          git push origin master
          

          在下次提交时忽略该文件夹的步骤

          要从下一次提交中忽略该文件夹,请在根目录中创建一个名为 .gitignore 的文件 并将该文件夹名称放入其中。想放多少就放多少

          .gitignore 文件将如下所示

          /FolderName
          

          【讨论】:

          • 这正是我想要的。谢谢:)
          • 我很高兴它帮助了@Rohit Singh
          【解决方案8】:

          我这样做:

          git rm --cached `git ls-files -i --exclude-from=.gitignore` 
          git commit -m 'Removed all files that are in the .gitignore' 
          git push origin master
          

          这将删除您的 git 忽略中的所有文件/文件夹,而您必须手动选择每个文件/文件夹


          这对我来说似乎已经停止工作了,我现在这样做了:

           git rm -r --cached . 
           git add .
           git commit -m 'Removed all files that are in the .gitignore' 
           git push origin master
          

          【讨论】:

          • 谢谢,这对我帮助很大!如果你使用的是windows powershell,你可以foreach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
          • 尝试了第二种方法,它从我的本地 git 中删除了所有文件!
          • 我认为您应该导航到子目录并执行此操作。如果我错了,请纠正我。
          • 孩子们,今天我们学到了什么? “不要运行你在 Stack Overflow 上找到的随机代码!”
          • Kris 的第二种方法效果很好。此命令如何删除 @artnikpro 报告的本地文件。它只会从索引中删除文件,而不是物理上的驱动器。
          【解决方案9】:

          .gitignore 文件中的规则仅适用于未跟踪的文件。由于该目录下的文件已在您的存储库中提交,因此您必须取消暂存它们,创建提交并将其推送到 GitHub:

          git rm -r --cached some-directory
          git commit -m 'Remove the now ignored directory "some-directory"'
          git push origin master
          

          如果不重写存储库的历史记录,则无法从历史记录中删除文件 - 如果其他人正在使用您的存储库,或者您正在多台计算机上使用它,则不应这样做。如果您仍然想这样做,可以使用git filter-branch 重写历史记录 - there is a helpful guide to that here

          另外,请注意git rm -r --cached some-directory 的输出将类似于:

          rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
          rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
          rm 'some-directory/.htaccess'
          rm 'some-directory/logo.jpg'
          

          rm 是 git 对存储库的反馈;文件仍在工作目录中。

          【讨论】:

          • 如果别人拉,现在被忽略的文件会被他们删除还是保持不变?
          • @Martin Konicek:如果拉取这些更改的用户没有对这些文件进行任何修改,那么它们将被删除。
          • @MarkLongair -r--cached 有什么作用。谢谢。
          • @Labanino: -r 表示递归,如果你正在处理整个目录,这是必要的。 --cached 覆盖了 git 从工作目录中删除它们的正常行为暂存删除以进行提交,并使 git 仅在准备提交的暂存区域上操作。这是你告诉 git 你想保留文件的本地副本的方式。
          • 这很好用,但我必须先做:git reset name_of_file 才能使上述内容起作用
          猜你喜欢
          • 2012-01-19
          • 2016-03-05
          • 1970-01-01
          • 2011-09-12
          • 1970-01-01
          • 2019-03-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多