Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 如何删除工作目录中不再存在的提交文件_Git_Shell - Fatal编程技术网

Git 如何删除工作目录中不再存在的提交文件

Git 如何删除工作目录中不再存在的提交文件,git,shell,Git,Shell,我有一个repo,其中包含许多不再在工作目录中的文件,这些文件是在存储库的数月/数年中添加和删除的 我想创建一个包含所有这些文件列表的文件,这些文件存储在提交历史记录中,但不再需要,包括它们的位置。。i、 e /web/scripts/index.php /sql/tables.sql ... 然后,我希望有一个命令可以运行该文件并将其中引用的文件从提交历史记录中完全删除,类似于git rm--cached这样的命令只用于文件列表。简短回答 别名,然后运行(时要小心): 解释 David Un

我有一个repo,其中包含许多不再在工作目录中的文件,这些文件是在存储库的数月/数年中添加和删除的

我想创建一个包含所有这些文件列表的文件,这些文件存储在提交历史记录中,但不再需要,包括它们的位置。。i、 e

/web/scripts/index.php
/sql/tables.sql
...
然后,我希望有一个命令可以运行该文件并将其中引用的文件从提交历史记录中完全删除,类似于
git rm--cached
这样的命令只用于文件列表。

简短回答 别名,然后运行(时要小心):

解释 David Underhill的命令使用
过滤器分支
修改存储库的历史记录,删除给定文件路径的所有历史记录

整个脚本():

将此脚本保存到硬盘上的某个位置(例如
/path/to/deletation\u script.sh
),并确保其可执行(
chmod+x/path/to/deletation\u script.sh

然后:

要获得一个:

把这一切结合起来 对于已删除文件的列表,只需连接
git delete
即可处理列表中的每个文件:

$ git delete `git log --all --pretty=format: --name-only --diff-filter=D`

测试/示例使用
  • 创建包含添加、重命名和删除的虚拟存储库:

    mkdir test_repo
    cd test_repo/
    git init
    echo "Dummy content" >> stays.txt
    git add stays.txt && git commit -m "First file, will stay"
    echo "Rename content" >> will_rename.txt
    git add will_rename.txt && git commit -m "Going to rename"
    echo "Delete this file" >> will_delete.txt
    git add will_delete.txt && git commit -m "Delete this file"
    git mv will_rename.txt renamed.txt && git commit -m "File renamed"
    git rm will_delete.txt && git commit -m "File deleted"
    
  • 检查历史记录:

    $ git whatchanged --oneline
    d768c58 File deleted
    :100644 000000 7a4187c... 0000000... D  will_delete.txt
    96aadf0 File renamed
    :000000 100644 0000000... 94a12c7... A  renamed.txt
    :100644 000000 94a12c7... 0000000... D  will_rename.txt
    3ba05fa Delete this file
    :000000 100644 0000000... 7a4187c... A  will_delete.txt
    c88850a Going to rename
    :000000 100644 0000000... 94a12c7... A  will_rename.txt
    6db6015 First file, will stay
    :000000 100644 0000000... f3ae800... A  stays.txt
    
  • 删除旧文件:

    $ git delete `git log --all --pretty=format: --name-only --diff-filter=D`
    Rewrite 8c2009db5ac05b27cd065482da94dec717f5ef4a (8/9)rm 'will_delete.txt'
    Rewrite e1348d588597f2f6dd63cade081e0fbdf8692c74 (9/9)
    Ref 'refs/heads/master' was rewritten
    Counting objects: 27, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (22/22), done.
    Writing objects: 100% (27/27), done.
    Total 27 (delta 12), reused 10 (delta 0)
    
  • 现在检查存储库。请注意,删除的内容已从历史记录中删除,重命名显示为文件最初是以这种方式添加的

    c800020 File renamed
    :000000 100644 0000000... 94a12c7... A  renamed.txt
    0a729d7 First file, will stay
    :000000 100644 0000000... f3ae800... A  stays.txt
    

  • 根据@David的回答,如果您想格外小心并确保没有删除任何随后在历史记录中添加的文件,请使用以下命令块,而不是使用
    git delete$(git log--all--pretty=format:--name only--diff filter=D)
    (考虑将其作为函数添加到
    .bashrc
    ):


    你确定要这样做吗?你可能会删除非常有价值的信息。包括文件的历史版本,如果Git没有意识到你在这种情况下进行了重命名。这也会让其他任何拉取该存储库的人陷入混乱。这被称为重写历史,受到高度反对。我完全同意Guvante和andrew—您应该在不与他人共享的存储库上执行此操作的唯一情况。如果您已经测试了备份,并且对这样一个过程所做的更改感到满意,那么就继续执行此操作。但是请注意—这样做可能会产生很多问题。只有我使用repo,并且我主要将其用于备份。我从一个大型repo开始,并且我一直在压缩和重构其中的代码。历史记录中存储了数千个文件,但从工作副本中删除了。我知道我再也不需要它们了,所以我只想从回购历史记录中删除它们,因为这只会占用不必要的空间。我已经阅读了它并运行了
    git delete git log--all--pretty=format:--n仅限ame--diff filter=D
    但别名'delete'的扩展失败;'sh'不是git命令。我做错了什么?您使用的是什么操作系统?如果不是*NIX系统,您如何运行git?(我上面提供的脚本是一个bash脚本——如果您运行的是Cygwin,您可以做到这一点,但它使用的GNU实用程序在Windows系统上是找不到的)。此外,我假设您只是没有正确使用标记语法,但正确的命令是
    git delete`git log--all--pretty=format:--name only--diff filter=D`
    (backtick扩展是关键)。使用Ubuntu12.04,我确实得到了正确的命令,并且安装了sh,但它仍然无法工作。对不起,这完全是我的错-我的Git别名语法错误。你需要在shell命令之前放置一个
    。我更新了我的答案(您需要使脚本可执行,并更改
    alias
    命令)。
    mkdir test_repo
    cd test_repo/
    git init
    echo "Dummy content" >> stays.txt
    git add stays.txt && git commit -m "First file, will stay"
    echo "Rename content" >> will_rename.txt
    git add will_rename.txt && git commit -m "Going to rename"
    echo "Delete this file" >> will_delete.txt
    git add will_delete.txt && git commit -m "Delete this file"
    git mv will_rename.txt renamed.txt && git commit -m "File renamed"
    git rm will_delete.txt && git commit -m "File deleted"
    
    $ git whatchanged --oneline
    d768c58 File deleted
    :100644 000000 7a4187c... 0000000... D  will_delete.txt
    96aadf0 File renamed
    :000000 100644 0000000... 94a12c7... A  renamed.txt
    :100644 000000 94a12c7... 0000000... D  will_rename.txt
    3ba05fa Delete this file
    :000000 100644 0000000... 7a4187c... A  will_delete.txt
    c88850a Going to rename
    :000000 100644 0000000... 94a12c7... A  will_rename.txt
    6db6015 First file, will stay
    :000000 100644 0000000... f3ae800... A  stays.txt
    
    $ git delete `git log --all --pretty=format: --name-only --diff-filter=D`
    Rewrite 8c2009db5ac05b27cd065482da94dec717f5ef4a (8/9)rm 'will_delete.txt'
    Rewrite e1348d588597f2f6dd63cade081e0fbdf8692c74 (9/9)
    Ref 'refs/heads/master' was rewritten
    Counting objects: 27, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (22/22), done.
    Writing objects: 100% (27/27), done.
    Total 27 (delta 12), reused 10 (delta 0)
    
    c800020 File renamed
    :000000 100644 0000000... 94a12c7... A  renamed.txt
    0a729d7 First file, will stay
    :000000 100644 0000000... f3ae800... A  stays.txt
    
    current=($(git ls-files))
    tracked=($(git log --all --pretty=format: --name-only --diff-filter=D | xargs))
    deleted=()
    resurrected=()
    for file in "${tracked[@]}"; do
    if [[ " ${current[@]} " =~ " $file " ]]; then
      resurrected+=("$file")
    else
      deleted+=("$file");
    fi
    done
    echo "Deleted: ${deleted[@]}"
    echo "Resurrected: ${resurrected[@]}"
    git delete "${deleted[@]}"