专栏首页编程思想之路git撤销修改各种情况

git撤销修改各种情况

如何在Git里撤销(几乎)任何操作

一、撤销一个已经公开的改变

场景:已经执行了gitpush,将修改发送到了github,需要撤销某一个commit。

方法:git revert<commit版本号>,则改commit的所有改变都会被反转。这是git最安全、最基本的撤销场景。

二、修正最后一个commit消息

场景:在最后一条commit消息里有一个笔误,已经执行git commit –m’xxx’,但在push之前发现说明信息有误

方法:git commit–-amend 或者git commit –amend –m’正确的信息’

原理:git commit–amend会用一个新的commit更新并替换最近的commit,这个心的commit会把任何修改内容和上一个commit的内容结合起来。如果当前没有提出任何修改,这个操作会把上次的commit消息重写一遍。

三、撤销本地修改

场景:git add后恢复,撤销git add。

方法:git checkout– filename

此种撤销会使任何修改完全消失,所以使用前最好用git diff确认下。

四、重置本地的修改

场景:在本地提交了一些东西(还没有push),希望撤销前面的三次提交。

方法:git reset <lastgood SHA>或git reset –hard <last good SHA>

原理:git reset会把代码库历史返回到指定的SHA状态。这样就像这些提交从来没有发生过。缺省情况下,git reset会保留工作目录。这样提交是没有了,但是修改内容还在磁盘上。这是一种安全选择,但通常希望一步就撤销提交及修改内容,这就是—hard选项的功能了。

五、在撤销了本地修改之后再恢复

场景:提交了几个commit后,用git reset –-hard撤销了这些修改,希望还原这些修改。

方法:git reflog和git reset或git checkout

原理:git reflog对于恢复项目历史是一个超棒的资源。可以恢复几乎任何东西——任何你commit过得东西。

一些注意事项:

l  它涉及的只是HEAD的改变。在切换分支、用git commit进行提交、以及用git reset撤销commit时,HEAD都会改变,但是当用git checkout -- <bad filrname>时,HEAD并不会改变,因此reflog也无法恢复。

l  git reflog不会永远保持。Git会定期清理那些用不到的对象,不要指望几个月前的提交还在那里。

l  不能用reflog来恢复另一个开发者没有push过得commit。

l  如果下网准确恢复项目的历史到某个时间点,用gitreset—hard<SHA>

l  如果希望重建工作目录里的一个或多个文件,让它们恢复到某个时间点的状态,用git checkout <SHA> -- <filename>

l  如果希望把这些commit里的某一个重新提交到代码库,用git cherry-pick <SHA>

六、利用分支的另一种做法

场景:进行了一些提交,然后意识到开始check out的是master分支。希望提交到另一个分支(feature)。

方法:git branchfeature,git reset –-hard origin/master,and git checkoutfeature

原理:gitcheckout –b <name>创建新的分支,这是创建新分支并马上check out的流行捷径,但是如果不希望马上切换分支。这里。git branch feature创建一个叫做feature的新分支并指向最近的commit,但还是checkout在master分支上。下一步,在提及任何新的commit之前,用git reset –-hard把master分支倒回到origin/master。不过那些commit还在feature中。最后,用git checkout切换到新的feature分支,并且让你最近所有的工作都完好无损。

七、在master繁殖的基础上创建了feature分支,但master分支已经滞后origin/master很多。现在master分支已经和origin/master同步,你希望在feature上的提交从现在开始,而不是从滞后很多的地方开始。

方法:git checkoutfeature和git rebase master

原理:要达到这个效果,你本来可以通过git reset (不加,--hard,这样可以在磁盘上保留修改)和git checkout –b <new branch name>然后再重新提交修改,不过这样做的话就会失去提交历史。

git rebase master会做如下事情:

Ø  首先他会找到你当前check out的分支和master分支的共同祖先。

Ø  然后它reset当前check out的分支到那个共同祖先,在一个临时保存区存放所有之前的提交。

Ø  然后它把当前check out的分支提交到master的末尾部分,并从临时保存区重新把存放的commit提交到master分支的最后一个commit之后。

八、大量的撤销/恢复

场景:进行了很多次提交,但是发现只需要其中一部分,其他提交需要舍弃。

方法:git rebase–i <earlier SHA>

原理:-i 参数让rebase进入“交互模式”。它开始类似于前面讨论的rebase,但在重新进行提交之前,它会暂停下来并允许详细修改每个提交。

rebase –I 会打开你的缺省文本编译器,里面列出候选的提交。前面两列是键:第一个是选定命令,对应第二列里的SHA确定的commit。缺省情况下,rebase–i假定每个commit都要通过pick命令。

要丢弃一个commit,只要在编辑器里删除那一行就可以了。如果你需要commit的内容,而是对commit消息进行编辑,可以使用reword命令。把第一列里的pick替换为reword(或者直接用r)。有人会觉得这里直接重写commit消息就行了,但是这样不管用rebase –i会忽略SHA列前面的任何东西,它后面的文本只是来帮助我们记住这个commit是来干嘛的。当你完成rebase –i的操作之后,你会被提示输入需要编写的任何commit消息。

如果比需要把两个commit合并到一起,可以使用squash或者fixup命令。Squash和fixup会向上合并,带有这两个命令的commit会被合并它的前一个commit里。如果选择squash,git会提示给新合并的commit一个新的commit消息;fixup则会把合并清单里第一个commit的消息直接给新合并的commit。当你保存并退出编辑器时,git会按从顶部到底部的顺序运用你的commit。可以通过在保存前修改commit顺序来改变运用的顺序。

九、停止追踪一个文件

场景:偶然把application.log加到代码库里了,现在每次运行应用,git都会报告在application.log里有未提交的修改。你把*.login放到了.gitignore文件里,可文件还是在代码库里,怎么才能告诉git撤销对这个文件的追踪呢?

方法:git rm –cachedapplication.log

原理:虽然.gitignore会阻止git追踪文件的修改,甚至不关心文件是否存在,但这只是针对于那些以前从来没有追踪过得文件。一旦有个文件被加入提交,git就会持续关注该文件的改变。如果你希望从git的追踪对象中删除那个本应忽略的文件,git rm –-cached会从追踪对象中删除它,但让文件在磁盘上保持原封不动。因为现在它已经被忽略了,你再git status里就不会再看见这个文件,也不会再偶然提交该文件的修改了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ubuntu系统上配置git

    1,首先第一步检查一下本机是否已经安装了git 随便到一个git目录下执行git status或者其他git命令,如果本机没有安装,则会提示你去安装,ubunt...

    fanfan
  • 带你解锁蓝牙skill(二)

    紧接着带你解锁蓝牙skill(一)继续分析 3>,Pbap配置 Pbap:Phone Book Access Profile是说共享联系人协议,具体定义...

    fanfan
  • Android6.0之修改或者查看系统属性值

    系统属性值存在于system.prop文件中,也有一些存在于settings中 1,查看settingsprovider中的值的方法 命令为adb shell ...

    fanfan
  • Git合并指定commit到当前分支

    有时我们需要将指定的某一次commit合并到当前分支,比如线上的一次bugfix,只合并需要的commits。

    JouyPub
  • git进行版本控制管理

    1、获取远程最新代码后,则需要从本地master分支切换到开发分支。(此处我们以每个新功能为一个新的开发分支)

    李才哥
  • 撤销远程提交-每天三分钟玩转Git (6)

    要是我们"不小心"把骂老板的话给提交到远程了,马上其他同事都要看到了,要是被发现就全完了,这个时候我们还来得及撤销吗?

    机智的程序员小熊
  • 记录我学github的路程(二)

    2015-12-09 更新 1,现在,本地有了一个库,你可能会想到GitHub创建一个库,并且关联起来。这样,远程的库既可以当作备份,又可以让其他人通过该仓库来...

    xcywt
  • 日常开发过程中实际场景下使用git的一些简单总结

    公司内部有代码仓库和 github 仓库邮箱不一致。例如已经全局配置了公司内的信息

    flytam
  • Git -- 分支与合并 (命令行+可视化工具p4merge)

    把所有的变化都放在master分支并不是最好的做法. 建议的做法是把变化放在分支里面.

    solenovex
  • Git -- 分支与合并 (命令行+可视化工具p4merge) Fast Forward 合并禁用 Fast Forward 合并自动合并解决合并的冲突

    基本命令 把所有的变化都放在master分支并不是最好的做法. 建议的做法是把变化放在分支里面. ? 至少应该准备一个feature分支之类的, 把变化都隔离开...

    solenovex

扫码关注云+社区

领取腾讯云代金券