我做了一个GIT提交。此提交包含多项更改,包括文件删除。
我已经做了其他提交。
所有提交都已被推送,拉开请求已开启审核(尚未批准或合并)。
现在我想从上一次提交中删除文件删除。那是我想撤消的 ONLY 。也就是说,我想在之前的提交中保留所有其他更改。
我该怎么做?
答案 0 :(得分:2)
git log --diff-filter=D --summary
获取已删除文件的所有提交让我们破解此命令以查看其工作原理--diff-filter=D
标记可帮助您搜索提及delete mode
的摘要
git checkout $commit~1 filename
恢复已删除的文件。 $commit~1
表示您应该添加提交的名称。像1d0c9ef6eb4e39488490543570c31c2ff594426c
这样的东西,其中$ commit是指定提交的第n个孙子 - Link
希望这会有所帮助
答案 1 :(得分:1)
如果你想要做的就是撤消删除,那么它就很容易被处理
- 找到执行删除的提交ID
- 执行下面的cmd以检出文件
醇>
git checkout commitid filename
之后,该文件位于您的工作目录
中答案 2 :(得分:1)
自you have pushed this以来,您已允许其他人看到删除。
这不会阻止您丢弃这组提交以支持新的设置,但是如果您这样做,那么抓住这些提交的其他任何人都必须也丢弃这一组提交有利于一套新的。
您还在同一评论中提到了拉取请求。拉取请求本质上是一封电子邮件或其他通信消息,说:"嘿,我有一些我提供的提交,请立即接受。"如果的人可以接受他们,已经采取了他们,那么您现在处于这种问题状态。但如果他们没有采取它们,您可以尝试撤消您的拉取请求(并且可能会成功)。如果是这样,你就会摆脱问题。
因此,有两种途径可供选择:
第一条路径是最好的,如果它还不太晚。第二条路径通常是最好的,如果其他人已经收到了错误的提交,虽然在某些情况下,如果你能找到所有人谁已经这样做,并且他们都同意,你可以拥有它们所有丢弃不良提交并取而代之。
请记住,所有Git存储库都包含提交,每个提交都构成了存储库中历史记录的一部分。每个提交都有自己唯一的哈希ID - badf00d...
等 - 并包含先前提交的唯一ID。这些ID是历史记录链:
A <- B <- C <- D <-- master
名称 master
可让您(和Git)找到最新的提交,我们称之为分支的提示。在这里,提交D
和提交D
说&#34;我以前的提交是提交C
&#34;。所以名称master
&#34;指向&#34; D
和D
点回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
,您可以撤回旧的拉取请求......好吧:
现在让我们看看如何制作P
,然后Q'
和R'
,因为您已经拥有S
。我们使用交互式rebase:
git rebase -i
(这假设branch
将origin/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
复制到Q
并Q'
复制到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
答案 4 :(得分:0)
如果您没有推,请试试这个:
git reset --soft {commit tag or hash}
其中{commit tag或hash}是有问题的提交之前的提交。然后,您可以在重新提交之前基本上重新执行整个提交,根据需要撤消。
我希望你没有推!