关于版本控制:如何放弃Git中未分页的更改?

How do I discard unstaged changes in Git?

如何放弃不在索引中的工作副本更改?


对于当前工作目录中的所有未分页文件,请使用:

1
git checkout -- .

对于特定文件,请使用:

1
git checkout -- path/to/file/to/revert

这里的--是为了消除争论中的歧义。


另一个更快的方法是:

1
git stash save --keep-index --include-untracked

如果你不想透彻的话,你不需要包括--include-untracked

在那之后,如果你愿意的话,你可以用一个git stash drop命令丢掉这个藏身处。


似乎完整的解决方案是:

1
2
git clean -df
git checkout -- .

git clean删除所有未跟踪的文件(警告:虽然它不会删除.gitignore中直接提到的忽略文件,但它可能删除文件夹中的忽略文件),git checkout清除所有未跟踪的更改。


这将检查当前目录的当前索引,并向下丢弃当前目录中文件的所有更改。

1
git checkout .

或者检查索引中的所有文件,覆盖工作树文件。

1
git checkout-index -a -f


1
git clean -df

通过从当前目录开始递归删除不受版本控制的文件来清理工作树。

-d:删除未跟踪的目录和未跟踪的文件

-f:力(根据clean.requireForce设置可能不需要)

运行git help clean查看手册


我最喜欢的是

1
git checkout -p

这样可以有选择地还原块。

参见:

1
git add -p


由于没有答案表明我使用的是确切的选项组合,这里是:

1
2
git clean -dfx
git checkout .

这是所用git clean选项的联机帮助文本:

-d

删除未跟踪的目录以及未跟踪的文件。如果未跟踪的目录由其他Git存储库管理,则默认情况下不会删除该目录。如果您真的想删除这样的目录,可以使用两次-f选项。

-f

如果git配置变量clean.requireForce未设置为false,则git clean将拒绝删除文件或目录,除非给定-f-n-i。Git将拒绝删除.git子目录或文件中的目录,除非给出第二个-f目录。

-x

不要使用来自EDOCX1(每个目录18)和$GIT_DIR/info/exclude的忽略规则,但仍要使用-e选项提供的忽略规则。这允许删除所有未跟踪的文件,包括生成产品。这可以用来(可能与git reset一起)创建一个原始的工作目录来测试一个干净的构建。

另外,git checkout .需要在回购的根目录中完成。


我真的发现这篇文章有助于解释何时使用什么命令:http://www.szakmeister.net/blog/2011/oct/12/reverting-changes-git/

有几个不同的情况:

  • 如果您还没有准备好文件,那么您可以使用git checkout。签出"更新工作树中的文件以匹配索引中的版本"。如果文件没有被转移(也就是添加到索引中)。这个命令基本上会将文件还原为上次提交的内容。

    git checkout -- foo.txt

  • 如果您已经转移了文件,那么使用git reset。重置将更改索引以匹配提交。

    git reset -- foo.txt

  • 我怀疑使用git stash是一种流行的选择,因为它的危险性要小一些。如果在使用git reset时不小心吹走了太多,您可以返回到它。默认情况下,重置是递归的。

    请看上面的文章以获取进一步的建议。


    最简单的方法是使用以下命令:

    此命令用于放弃工作目录中的更改-

    1
    git checkout -- .

    https://git-scm.com/docs/git-checkout

    在git命令中,通过使用以下方法来存储未跟踪的文件:

    1
    git stash -u

    网址:http://git-scm.com/docs/git-stash


    如果您只想删除对现有文件的更改,请使用checkout(此处记录)。

    1
    git checkout -- .
    • 未指定分支,因此它将签出当前分支。
    • 双连字符(--告诉git,下面的内容应该作为它的第二个参数(path),您跳过了分支的规范。
    • 句点(.表示所有路径。

    如果要删除自上次提交以来添加的文件,请使用clean(此处记录):

    1
    git clean -i
    • -i选项启动交互式clean以防止错误删除。
    • 其他一些选项可用于更快的执行;请参阅文档。

    如果要将更改移动到保留空间以供以后访问,请使用stash(此处记录):

    1
    git stash
    • 所有更改都将移动到Git的存储库中,以便以后访问。
    • 一些选项可用于更细微的存储;请参阅文档。


    如果您对保留未分页的更改不感兴趣(特别是如果分阶段的更改是新文件),我发现这很方便:

    1
    git diff | git apply --reverse


    当你输入git状态时,(使用"git checkout--…"放弃工作目录中的更改)如图所示。

    git checkout -- .


    git checkout -f

    man git-checkout

    -f, --force

    切换分支时,即使索引或工作树与头不同,也要继续。这用于丢弃本地更改。

    从索引中签出路径时,不要在未合并的条目上失败;而是忽略未合并的条目。


    你可以使用git stash-如果出了问题,你仍然可以从stash恢复过来。与此处的其他答案类似,但此选项还删除所有未分页的文件和所有未分页的删除:

    1
    2
    git add .
    git stash

    如果你检查一切正常,把藏品扔掉:

    1
    git stash drop

    Bilal Maqsood和git clean的回答对我也有帮助,但在藏匿处我有更多的控制权——如果我不小心做了什么,我仍然可以取回我的零钱。

    更新

    我想还有一个变化(不知道为什么以前这样对我有效):

    git add . -A代替git add .

    如果没有-A文件,删除的文件将不会被暂存。


    我没有放弃更改,而是将遥控器重置为原点。注意-此方法是将文件夹完全还原为repo文件夹。

    所以我这样做是为了确保当我git重置时它们不在那里(稍后-排除源站/分支名称上的gitignores)

    注意:如果要保留尚未跟踪的文件,但不在gitignore中,您可能希望跳过此步骤,因为它将擦除远程存储库中找不到的未跟踪文件(谢谢@xtrmjosh)。

    1
    git add --all

    然后我

    1
    git fetch --all

    然后我重置为原点

    1
    git reset --hard origin/branchname

    这将使它回到正方一。就像重新克隆分支一样,同时将所有gitignored文件保留在本地和适当的位置。

    以下按用户更新的评论:变量将重置为用户当前所在的分支。

    1
    git reset --hard @{u}


    尝试了上面的所有解决方案,但仍然无法删除新的、未老化的文件。

    使用git clean -f删除这些新文件-但要小心!注意强制选项。


    只需使用:

    1
    git stash -u

    完成。容易的。

    如果你真的关心你的藏匿处,那么你可以跟着git stash drop。但在这一点上,你最好使用(来自Mariusz Nowak):

    1
    2
    git checkout -- .
    git clean -df

    尽管如此,我还是最喜欢git stash -u,因为它只在一个命令中"丢弃"所有跟踪和未跟踪的更改。然而,git checkout -- .只丢弃跟踪的变化,git clean -df只丢弃未跟踪的更改…输入这两个命令的工作量太大了:)


    简单地说

    1
    git stash

    它将删除所有本地更改。你以后也可以说

    1
    git stash apply

    或流行音乐流行歌曲


    这甚至在正常git权限之外的目录中也可以工作。

    1
    sudo chmod -R 664 ./* && git checkout -- . && git clean -dfx

    最近发生在我身上


    1
    2
    cd path_to_project_folder  # take you to your project folder/working directory
    git checkout .             # removes all unstaged changes in working directory

    无论回购处于何种状态,您都可以重置为以前的任何承诺:

    1
    git reset --hard <commit hash>

    这将放弃在提交之后所做的所有更改。


    另一种消除新文件的方法比git clean-df更具体(它允许您除去一些文件,不一定全部),是先将新文件添加到索引中,然后存储,然后删除存储。

    当由于某种原因,您无法通过某种普通机制(如rm)轻松删除所有未跟踪的文件时,此技术非常有用。


    在我看来,

    1
    git clean -df

    应该有技巧。根据Git清洁文件

    git-clean - Remove untracked files from the working tree

    描述

    Cleans the working tree by recursively removing files that
    are not under version control, starting from the current directory.

    Normally, only files unknown to Git are removed, but if the -x option
    is specified, ignored files are also removed. This can, for example,
    be useful to remove all build products.

    If any optional ... arguments are given, only those paths are
    affected.

    选项

    -d Remove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is
    not removed by default. Use -f option twice if you really want to
    remove such a directory.

    -f
    --force If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to run unless given -f, -n or -i.


    如果您使用的是存储库的一个分支,在该分支中定期与另一个repo同步(例如pull请求),那么下面的内容实际上只是一个解决方案。简短回答:删除fork并重新格式化,但请阅读github上的警告。

    我也遇到过类似的问题,可能不完全相同,我很遗憾地说,我的解决方案并不理想,但最终是有效的。

    我经常会收到这样的git状态消息(至少包含2/4个文件):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ git status
    # Not currently on any branch.
    # Changes to be committed:
    #   (use"git reset HEAD <file>..." to unstage)
    #
    #       modified:   doc/PROJECT/MEDIUM/ATS-constraint/constraint_s2var.dats
    #       modified:   doc/PROJECT/MEDIUM/ATS-constraint/parsing/parsing_s2var.dats
    #
    # Changes not staged for commit:
    #   (use"git add <file>..." to update what will be committed)
    #   (use"git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   doc/PROJECT/MEDIUM/ATS-constraint/constraint_s2Var.dats
    #       modified:   doc/PROJECT/MEDIUM/ATS-constraint/parsing/parsing_s2Var.dats

    敏锐的眼睛会注意到这些文件中的"兴奋剂"是一个单独的字母,以防万一。不知何故,我不知道是什么引导我沿着这条路径开始(因为我自己没有从上游repo处理这些文件),我已经切换了这些文件。尝试本页(和其他页)列出的许多解决方案似乎没有帮助。

    我可以通过删除分叉的存储库和所有本地存储库并重新格式化来解决这个问题。仅此一项是不够的;上游必须将有问题的文件重命名为新文件名。只要你没有任何未被限制的工作,没有维基,也没有任何与上游存储库不同的问题,你就应该很好。上游可能对你不太满意,至少可以说。至于我的问题,这无疑是一个用户错误,因为我不太精通git,但事实上,要解决git问题还远不容易。


    当你想把藏品转移给其他人时:

    1
    2
    3
    4
    5
    6
    7
    8
    # add files
    git add .  
    # diff all the changes to a file
    git diff --staged > ~/mijn-fix.diff
    # remove local changes
    git reset && git checkout .
    # (later you can re-apply the diff:)
    git apply ~/mijn-fix.diff

    [编辑]正如评论所述,可以命名藏品。好吧,如果你想分享你的藏品,就用这个;)


    如果所有的阶段性文件都被提交了,那么可以简单地重置分支,例如从您的GUI中单击三次鼠标:branch,reset,yes!

    所以我在实践中经常做的是恢复不需要的本地更改,提交所有好的东西,然后重新设置分支。

    如果好的东西是在一个单一的提交中提交的,那么如果您最终想要以一点不同的方式提交它,那么您可以使用"修正最后提交"将其恢复到阶段性或非阶段性。

    这可能不是您在寻找解决问题的技术解决方案,但我发现这是一个非常实用的解决方案。它允许您有选择地放弃未保存的更改,重新设置您不喜欢的更改并保留您所做的更改。

    总之,我只需提交、分支重置和修改最后一次提交。


    如果您是在子模块的情况下,没有其他解决方案起作用,请尝试:

    • 要检查问题是什么(可能是"脏"情况),请使用:

      git diff

    • 清除堆积物

      git submodule update


    我遇到了一个奇怪的情况,文件总是不稳定的,这有助于我解决问题。

    git rm .gitattributes
    git add -A
    git reset --hard


    您可以创建自己的别名,该别名以描述性的方式描述如何执行该操作。

    我使用下一个别名放弃更改。

    放弃工作树中文件(列表)的更改

    1
    discard = checkout --

    然后您可以将其用作下一个选项来放弃所有更改:

    1
    discard .

    或者只是一个文件:

    1
    discard filename

    否则,如果您要放弃所有更改以及未跟踪的文件,我将混合使用签出和清理:

    清除并丢弃工作树中的更改和未跟踪的文件

    1
    cleanout = !git clean -df && git checkout -- .

    因此使用简单如下:

    1
    cleanout

    现在可以在下一个包含大量别名的Github repo中使用:

    • https://github.com/gitalias/gitalias/网址:

    如果您刚刚更改了文件的权限(这是在DOS/windoze上),所有解决方案都不起作用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    Mon 23/11/2015-15:16:34.80 C:\...\work\checkout\slf4j+> git status
    On branch SLF4J_1.5.3
    Changes not staged for commit:
      (use"git add ..." to update what will be committed)
      (use"git checkout -- ..." to discard changes in working directory)

            modified:   .gitignore
            modified:   LICENSE.txt
            modified:   TODO.txt
            modified:   codeStyle.xml
            modified:   pom.xml
            modified:   version.pl

    no changes added to commit (use"git add" and/or"git commit -a")

    Mon 23/11/2015-15:16:37.87 C:\...\work\checkout\slf4j+> git diff
    diff --git a/.gitignore b/.gitignore
    old mode 100644
    new mode 100755
    diff --git a/LICENSE.txt b/LICENSE.txt
    old mode 100644
    new mode 100755
    diff --git a/TODO.txt b/TODO.txt
    old mode 100644
    new mode 100755
    diff --git a/codeStyle.xml b/codeStyle.xml
    old mode 100644
    new mode 100755
    diff --git a/pom.xml b/pom.xml
    old mode 100644
    new mode 100755
    diff --git a/version.pl b/version.pl
    old mode 100644
    new mode 100755

    Mon 23/11/2015-15:16:45.22 C:\...\work\checkout\slf4j+> git reset --hard HEAD
    HEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore

    Mon 23/11/2015-15:16:47.42 C:\...\work\checkout\slf4j+> git clean -f

    Mon 23/11/2015-15:16:53.49 C:\...\work\checkout\slf4j+> git stash save -u
    Saved working directory and index state WIP on SLF4J_1.5.3: 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore
    HEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore

    Mon 23/11/2015-15:17:00.40 C:\...\work\checkout\slf4j+> git stash drop
    Dropped refs/stash@{0} (cb4966e9b1e9c9d8daa79ab94edc0c1442a294dd)

    Mon 23/11/2015-15:17:06.75 C:\...\work\checkout\slf4j+> git stash drop
    Dropped refs/stash@{0} (e6c49c470f433ce344e305c5b778e810625d0529)

    Mon 23/11/2015-15:17:08.90 C:\...\work\checkout\slf4j+> git stash drop
    No stash found.

    Mon 23/11/2015-15:17:15.21 C:\...\work\checkout\slf4j+> git checkout -- .

    Mon 23/11/2015-15:22:00.68 C:\...\work\checkout\slf4j+> git checkout -f -- .

    Mon 23/11/2015-15:22:04.53 C:\...\work\checkout\slf4j+> git status
    On branch SLF4J_1.5.3
    Changes not staged for commit:
      (use"git add ..." to update what will be committed)
      (use"git checkout -- ..." to discard changes in working directory)

            modified:   .gitignore
            modified:   LICENSE.txt
            modified:   TODO.txt
            modified:   codeStyle.xml
            modified:   pom.xml
            modified:   version.pl

    no changes added to commit (use"git add" and/or"git commit -a")

    Mon 23/11/2015-15:22:13.06 C:\...\work\checkout\slf4j+> git diff
    diff --git a/.gitignore b/.gitignore
    old mode 100644
    new mode 100755
    diff --git a/LICENSE.txt b/LICENSE.txt
    old mode 100644
    new mode 100755
    diff --git a/TODO.txt b/TODO.txt
    old mode 100644
    new mode 100755
    diff --git a/codeStyle.xml b/codeStyle.xml
    old mode 100644
    new mode 100755
    diff --git a/pom.xml b/pom.xml
    old mode 100644
    new mode 100755
    diff --git a/version.pl b/version.pl
    old mode 100644
    new mode 100755

    解决此问题的唯一方法是手动重置已更改文件的权限:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Mon 23/11/2015-15:25:43.79 C:\...\work\checkout\slf4j+> git status -s | egrep"^ M" | cut -c4- | for /f"usebackq tokens=* delims=" %A in (`more`) do chmod 644 %~A

    Mon 23/11/2015-15:25:55.37 C:\...\work\checkout\slf4j+> git status
    On branch SLF4J_1.5.3
    nothing to commit, working directory clean

    Mon 23/11/2015-15:25:59.28 C:\...\work\checkout\slf4j+>

    Mon 23/11/2015-15:26:31.12 C:\...\work\checkout\slf4j+> git diff

    如果几乎不可能排除对文件的修改,您是否考虑忽略它们?如果此语句是正确的,并且在开发期间您不会触摸这些文件,则此命令可能很有用:

    git update-index --assume-unchanged file_to_ignore


    只需使用:

    1
    git stash -k -u

    这将存储未保存的更改和未跟踪的文件(新文件),并保留阶段性文件。

    它比reset/checkout/clean要好,因为你可能希望他们以后再回来(git stash pop)。把它们藏起来总比扔掉好。


    如果您的本地存储库中存在某些强制提交的残余,那么您可能会尝试使用上述所有建议删除所有本地更改,但没有任何效果。如果远程(源/分支名称)已由您或其他人修复,但本地存储库仍显示冲突,请运行:

    1
    2
    3
       git checkout branch_name
       git reset --hard origin/branch_name    
       git pull