Git从两次提交前回滚
几天前,我从master分支,并向Git从两次提交前回滚,git,Git,几天前,我从master分支,并向newbranch提交了两份后续承诺 后来,我注意到我所做的第一次提交中的一个文件不应该被更改。我还没有将任何内容推送到主分支,我所有的更改都在newbranch中。如何将newbranch中的这一个文件回滚到我最初从master分支时的位置?git checkout master--filepathgit checkout master--filepath在新分支上: git checkout HEAD~1 git checkout HEAD~1 file_n
newbranch
提交了两份后续承诺
后来,我注意到我所做的第一次提交中的一个文件不应该被更改。我还没有将任何内容推送到主分支,我所有的更改都在
newbranch
中。如何将newbranch
中的这一个文件回滚到我最初从master分支时的位置?git checkout master--filepath
git checkout master--filepath
在新分支上:
git checkout HEAD~1
git checkout HEAD~1 file_not_needed
git commit -a --amend
git cherry-pick new_branch
git branch -f new_branch HEAD
关于新科:
git checkout HEAD~1
git checkout HEAD~1 file_not_needed
git commit -a --amend
git cherry-pick new_branch
git branch -f new_branch HEAD
根据您想要的结果,有几种不同的方法来实现这一点 这个 开始时,您的提交历史记录如下所示(每个字母代表一次提交): (这种签出形式,
git checkout
,告诉git更改头的名称。在本例中,
头1
,意思是“查找提交头的名称并向后移动一个”,所以这表示从commitE
向后移动一个。由于这是一个特定的
,而不是一个分支名称,因此它还具有“分离头”效果。)
现在运行git checkout HEAD~1 filename
。为了对git更加明确,可以说git checkout HEAD~1--filename
。-->
表示“剩余参数是文件名,而不是分支或修订名”-如果省略-->
,git会尝试猜测它是分支名还是文件名
这种形式的签出
,带有--filename
参数,做了一些完全不同的事情:它说要像往常一样查找修订版头~1
,但这次,不要更改头
,只提取给定的文件。由于HEAD
现在命名了修订版D
,git又备份了一个修订版C
,并从该修订版中提取文件filename
的版本,并将其放入工作目录
(请注意,分支名称master
也命名为revisionC
,因此此时您可以编写git checkout master--filename
。)
接下来,git commit-a--amend
告诉git添加任何更改的文件。在这种情况下,您实际上不需要它,但一般来说,这会添加您已修复的其他文件,然后执行“amend commit”。“修改提交”意味着“创建一个新提交,但使其父提交与我们的父提交相同”。这将创建一个新的提交,我们将其称为D'
,其父级为C
。与往常一样,新提交将成为标题
。由于HEAD
已分离,因此尚未移动分支名称。生成的提交树如下所示:
A - B - C <-- master
| \
\ D
\ \
\ E <-- newbranch
\
D' <-- HEAD
现在,您只需要给头
指定一个分支名称。然后可以安全地删除newbranch
,或者将其重命名,然后将newnewnew
重命名为newbranch
:
git checkout -b newnew # now HEAD=newnew which points to E'
git branch -m newbranch oldnew # rename out of the way
git branch -m newnew newbranch # and rename newnew to newbranch
(你可以把它缩短一点,但让我们继续…)
有一种更简单的方法来做同样的事情。只需运行
git-rebase-i master
。这意味着使用master
作为当前分支的“上游”来重新设置当前分支(newbranch
)的基础。也就是说,找到master
(这意味着D
和E
)之后的所有提交,并将它们重新设置到master
(这是它们以前的基础)。如果没有-i
这将是愚蠢的,将D
和E
重新设置为与以前完全相同的方式,这只是一种昂贵的方式,除了使用-i
git可以打开一个编辑器来执行一系列命令。这些命令将pick
提交D
和E
。将提交D
的选择
更改为编辑
,然后写出文件
然后,rebase将为您选择D
,并停止,让您修改提交。在shell中,输入:
git checkout master -- filename
git commit -a --amend
与前面一样,保存修改后的提交,它将变成D'
。然后运行:
git rebase --continue
Git现在将选择commitE
,并给出commitE'
。现在一切都完成了,这样重基就完成了,branchnewbranch
有了您想要的提交
这家公司做了一些不同的事情。它包含相同的
git签出主机--filename
(拼写为filepath
),但没有类似于rebase的序列
因此,与之前一样,您从以下内容开始:
A - B - C <-- master
\
D
\
E <-- HEAD=newbranch
A-B-C根据您想要的结果,有几种不同的方法可以做到这一点
这个
开始时,您的提交历史记录如下所示(每个字母代表一次提交):
(这种签出形式,git checkout
,告诉git更改头的名称。在本例中,
头1
,意思是“查找提交头的名称并向后移动一个”,所以这表示从commitE
向后移动一个。由于这是一个特定的
,而不是一个分支名称,因此它还具有“分离头”效果。)
现在运行git checkout HEAD~1 filename
。为了对git更加明确,可以说git checkout HEAD~1--filename
。-->
表示“剩余参数是文件名,而不是分支或修订名”-如果省略-->
,git会尝试猜测它是分支名还是文件名
这种形式的签出
,带有--filename
参数,做了一些完全不同的事情:它说要像往常一样查找修订版头~1
,但这次,不要更改头
,只提取给定的文件。由于HEAD
现在命名了修订版D
,git又备份了一个修订版C
,并从该修订版中提取文件filename
的版本,并将其放入工作目录
(请注意,分支机构名称master
也命名为修订版C
,
git rebase --continue
A - B - C <-- master
\
D
\
E <-- HEAD=newbranch