在说"rollback"时必须小心。如果你曾经在提交$A中有一个文件的先前版本,然后稍后又进行了两次独立的提交$B和$C的更改(所以你看到的是该文件的第三个迭代版本),如果你说"我想回到第一个版本",那么你真的是这个意思吗?
如果你想要摆脱第二和第三次迭代的更改,那么非常简单:
$ git checkout $A file
然后您提交结果。该命令会询问“我想从提交$A记录的状态检出文件”。
另一方面,如果您想要摆脱第二次迭代(即提交$B)带来的更改,同时保留提交$C对文件所做的更改,则需要还原$B。
$ git revert $B
git log
显示的是 提交,而你还没有 提交 这个更改(回滚)。如果你在回滚之后执行 git commit
,那么 git log
就会显示这个更改。 - ToolmakerSteve
git checkout Last_Stable_commit_Number -- fileName
2.将文件在Git中还原到特定分支
git checkout branchName_Which_Has_stable_Commit fileName
有趣的是,如果工作副本在名为foo
的目录中,git checkout foo
将不起作用;然而,git checkout HEAD foo
和git checkout ./foo
都可以:
$ pwd
/Users/aaron/Documents/work/foo
$ git checkout foo
D foo
Already on "foo"
$ git checkout ./foo
$ git checkout HEAD foo
以下是 rebase
的工作原理:
git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>
假设你有以下内容:
---o----o----o----o master \---A----B <my branch>
第一和第二个命令... 提交 git checkout git rebase master
...是为了检出你想要应用到
master
分支的更改的分支。rebase
命令将来自<my branch>
的提交(在master
中找不到)重新应用到master
的头部。换句话说,<my branch>
的第一个提交的父提交不再是master
历史中的先前提交,而是当前的master
头部。这两个命令与以下命令相同:git rebase master <my branch>
记住这个命令可能更容易,因为"base"和"modify"分支都是明确的。
最终的历史结果是:
最后两个命令...---o----o----o----o master \----A'----B' <my branch>
git checkout master git merge <my branch>
执行快进合并,将所有
<我的分支>
的更改应用到master
上。如果没有这一步,变基提交将不会被添加到master
中。最终结果如下:...
---o----o----o----o----A'----B' master, <my branch>
master
和<my branch>
都指向B'
。同时,从这个点开始,可以安全地删除<my branch>
的引用。git branch -d <my branch>
为目标文件执行首次重置操作
git reset HEAD path_to_file
第二次检查那个文件
git checkout -- path_to_file
如果您想将文件恢复到以前的提交版本(且要恢复的文件已经提交),则可以使用
git checkout HEAD^1 path/to/file
或者git checkout HEAD~1 path/to/file
然后只需将"新"版本进行分阶段和提交。
知道在合并的情况下提交可以有两个父级,你应该知道HEAD^1是第一个父级,HEAD~1是第二个父级。
如果树中只有一个父级,则任何一个都可以使用。
使用git别名,awk和shell函数来解决问题!
git prevision <N> <filename>
其中<N>
是要回滚文件<filename>
的版本数。例如,要撤销单个文件x/y/z.c
的上一个修订版本,请运行:
git prevision -1 x/y/z.c
将以下内容添加到您的gitconfig
文件中。
[alias]
prevision = "!f() { git checkout `git log --oneline $2 | awk -v commit="$1" 'FNR == -commit+1 {print $1}'` $2;} ;f"
该命令基本上:
- 对指定的文件执行
git log
- 从文件历史记录中选择适当的提交ID,并
- 为指定的文件执行
git checkout
到提交ID。
实际上,所有在这种情况下手动执行的操作都被包含在一个美丽高效的Git别名中 - git-prevision
这里提出了许多建议,大多数建议是使用 git checkout $revision -- $file
这样的命令。还有几种较为晦涩的替代方法:
git show $revision:$file > $file
而且,我经常使用这个功能来暂时查看特定的版本:
git show $revision:$file
或者git show $revision:$file | vim -R -
(提示: 如果$file
是相对路径,则需要在前面加上./
,以便git show $revision:$file
正常工作)
甚至更奇怪的是:
git archive $revision $file | tar -x0 > $file
git revert
。 在这种情况下,您只需要说:
eg revert foo/bar foo/baz
eg revert --in REVISON -- FILENAME
。--in
很重要。对于 Windows 用户:打开 git bash。执行 echo %PATH
。第一个路径应该在您的用户目录中,以 bin
结尾。创建该路径。将 eg 存储在那里。将其命名为 eg
,而不是 eg.txt
。 - koppor请注意,git checkout ./foo
和git checkout HEAD ./foo
不是完全相同的东西;举个例子:
$ echo A > foo
$ git add foo
$ git commit -m 'A' foo
Created commit a1f085f: A
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
$ echo B >> foo
$ git add foo
$ echo C >> foo
$ cat foo
A
B
C
$ git checkout ./foo
$ cat foo
A
B
$ git checkout HEAD ./foo
$ cat foo
A
(第二个add
将文件暂存到索引中,但不会被提交。)
Git checkout ./foo
表示从索引中还原路径./foo
;添加HEAD
指令告诉Git在执行还原之前将该路径在索引中还原为HEAD
版本。
git diff
时不要忘记加上--cached
参数。 - Geoffrey Hale