在GIT中,如何从包含其他更改的提交中删除文件删除?

时间:2017-02-20 11:12:56

标签: git

我做了一个GIT提交。此提交包含多项更改,包括文件删除。

我已经做了其他提交。

所有提交都已被推送,拉开请求已开启审核(尚未批准或合并)。

现在我想从上一次提交中删除文件删除。那是我想撤消的 ONLY 。也就是说,我想在之前的提交中保留所有其他更改。

我该怎么做?

5 个答案:

答案 0 :(得分:2)

  1. 使用git log --diff-filter=D --summary获取已删除文件的所有提交
  2. 让我们破解此命令以查看其工作原理--diff-filter=D标记可帮助您搜索提及delete mode的摘要

    1. 使用git checkout $commit~1 filename恢复已删除的文件。
    2. $commit~1表示您应该添加提交的名称。像1d0c9ef6eb4e39488490543570c31c2ff594426c这样的东西,其中$ commit是指定提交的第n个孙子 - Link

      希望这会有所帮助

答案 1 :(得分:1)

如果你想要做的就是撤消删除,那么它就很容易被处理

  
      
  1. 找到执行删除的提交ID
  2.   
  3. 执行下面的cmd以检出文件
      git checkout commitid filename
  4.   

之后,该文件位于您的工作目录

答案 2 :(得分:1)

you have pushed this以来,您已允许其他人看到删除。

这不会阻止您丢弃这组提交以支持新的设置,但是如果您这样做,那么抓住这些提交的其他任何人都必须丢弃这一组提交有利于一套新的。

您还在同一评论中提到了拉取请求。拉取请求本质上是一封电子邮件或其他通信消息,说:"嘿,我有一些我提供的提交,请立即接受。"如果的人可以接受他们,已经采取了他们,那么您现在处于这种问题状态。但如果他们没有采取它们,您可以尝试撤消您的拉取请求(并且可能会成功)。如果是这样,你就会摆脱问题。

因此,有两种途径可供选择:

  1. 收回破坏的拉取请求,用新的集合替换错误的提交集,并生成新的拉取请求;或
  2. 一直承认错误,留下错误的提交,并进行新的额外提交以撤消错误。
  3. 第一条路径是最好的,如果它还不太晚。第二条路径通常是最好的,如果其他人已经收到了错误的提交,虽然在某些情况下,如果你能找到所有人谁已经这样做,并且他们都同意,你可以拥有它们所有丢弃不良提交并取而代之。

    请记住,所有Git存储库都包含提交,每个提交都构成了存储库中历史记录的一部分。每个提交都有自己唯一的哈希ID - badf00d...等 - 并包含先前提交的唯一ID。这些ID是历史记录链:

    A <- B <- C <- D   <-- master
    

    名称 master可让您(和Git)找到最新的提交,我们称之为分支的提示。在这里,提交D和提交D说&#34;我以前的提交是提交C&#34;。所以名称master&#34;指向&#34; DD点回C。当然,C指向B,依此类推 - 虽然当我们达到有史以来的第一次提交时,它并没有指向任何地方,因为它是<\ n < em>第一次提交。这就是我们如何知道停止寻找。

    你做了一些错误的提交,所以让我们在其中绘制一个带有错误提交的提交链:

    ...--N              <-- origin/branch
          \
           O--X--Q--R   <-- (your pull request)
    

    这里X是错误的提交。我们希望使用良好的提交X替换 P,这就像错误提交一样,只是它不会删除文件。让我们不要担心如何你做出好的提交,但只是假设你可以制作P

    ...--N              <-- origin/branch
          \
           O--X--Q--R   <-- (your pull request), branch
            \
             P
    

    我们无法使用Q,因为它指向X。既然我们已经P,我们需要制作一个指向Q'的固定P(并且也没有删除该文件)。让我们画出:

    ...--N              <-- origin/branch
          \
           O--X--Q--R   <-- (your pull request)
            \
             P--Q'      <-- branch
    

    现在我们还需要R的副本,它指向Q'(同样在快照中没有删除文件):

    ...--N              <-- origin/branch
          \
           O--X--Q--R   <-- (your pull request)
            \
             P--Q'--R'  <-- branch
    

    现在你可以丢弃旧的拉取请求并制作一个新请求,指向R'

    如何采取任何一条路径

    我们将从第二个路径开始:始终承认错误,并修复混乱。这是因为它是到达第一个路径的最简单方法!

    同样,这或多或少是你现在所拥有的:

    ...--N              <-- origin/branch
          \
           O--X--Q--R   <-- branch, (your pull request)
    

    &#34;替换拉取请求&#34;只有当其他人已经在R结束你的不良提交时才会有效。如果有,则必须让他们放弃X-Q-R序列以支持新的P-Q'-R'序列。如果他们无法或不会放弃它,那么最好的办法是制作一个新的修正提交S。提交S只是将已删除的文件添加回来:其快照与R的快照相同,但文件已恢复。以下是您如何制作S的方法。它只需要两个Git命令:

    git checkout origin/branch -- path/to/file
    

    这将从path/to/file点的提交中提取origin/branch的版本,即从提交N。 (将任何其他提交命名,例如,通过其哈希ID,以从该特定提交中获取该文件的版本。)然后:

    # you can probably come up with a better commit message!
    git commit -m "fix-up: restore accidentally-deleted file"
    

    提交结果(git checkout具有&#34;预先添加&#34;提交的副作用,因此这次我们不需要单独的git add。这使你成为S,现在你拥有了这个:

    ...--N                 <-- origin/branch
          \
           O--X--Q--R--S   <-- branch
    

    您现在可以通过发出新的请求来停止,为您的上游存储库提供新的提交S并要求他们提取 。但是,如果他们尚未撤出R,您可以撤回旧的拉取请求......好吧:

    &#34;重写历史记录&#34;

    现在让我们看看如何制作P,然后Q'R',因为您已经拥有S 。我们使用交互式rebase:

    git rebase -i
    

    (这假设branchorigin/branch设置为其上游,它应该如此)。这会使您的编辑器调出一组五个pick命令:

    pick 1234567 commit subject for O     # the numbers will vary
    pick c0ffee1 commit subject for X     # these are the hash IDs
    pick badf00d commit subject for Q     # of each commit
    pick cafedad commit subject for R
    pick ....... fix-up: restore accidentally-deleted file
    

    请注意,最后一行包含我们的修复提交S中的提交主题。现在我们将该行移到pick命令之后,用于错误提交X,然后更改左侧的命令,将pick替换为{{1} }}:

    squash

    写出这个命令文件并退出编辑器,pick 1234567 commit subject for O pick c0ffee1 commit subject for X squash ....... fix-up: restore accidentally-deleted file pick badf00d commit subject for Q pick cafedad commit subject for R 提交git rebase与提交X结合起来(并给你一个写作的机会)由此产生的新提交消息)。这是更正后的提交S。当你写出新消息并再次退出编辑器时,Git会将P复制到QQ'复制到R,现在你真的有这个:

    R'

    请注意,...--N <-- origin/branch \ O--X--Q--R <-- (your old pull request) \ \ \ S [abandoned] \ P--Q'--R' <-- branch Q'具有与R'Q不同的哈希ID:这就是Git知道他们与众不同的方式,并且可以甚至在第一时间就拥有它们。你有重写历史&#34;因为你的分支名称R现在说&#34;去查看提交branch&#34;,当它过去说'#34;去看提交R'&# 34 ;.现在你真的可以丢弃旧的拉取请求并制作一个新请求,说&#34;请接受提交S&#34;。

答案 3 :(得分:0)

您可以从分支中恢复特定的commitId

git revert commitid

可以在gitk

中找到提交ID

答案 4 :(得分:0)

如果您没有推,请试试这个:

git reset --soft {commit tag or hash}

其中{commit tag或hash}是有问题的提交之前的提交。然后,您可以在重新提交之前基本上重新执行整个提交,根据需要撤消。

我希望你没有推!