Git 使用记录 - 各种撤销

@(版本控制)[git]

前面通过 Git使用记录 - 基础 一文记录了平时的一些git基础操作。由于篇幅限制,只能作为一个基础参考,更加详细建议阅读《git 权威指南》 或官方提供的文档

本文主要记录在不同情景下,如何恰当地撤销错误操作。

个人开发环境 ubuntu 14.04

说明:

  • $ 表示终端执行命令
  • # 命令注释
  • [] 表示可选

撤销本地(工作区)的修改

场景:我直接修改 pySerial.py 做个小测试, 测试后想取消掉那些修改。

$ git checkout pySerial.py
$ git status 
On branch master
Your branch is up-to-date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   pySerial.py

以上操作用于撤销保存在工作区修改,但是不会撤销暂存区中的修改。
由于修改还没记录到 git 中,撤销无法恢复,请慎重!

修正最后一个commit

场景:我修正了一个惊天大 bug,赶紧提交炫耀一下,然后下一秒,我发现提交说明拼写错误,好尴尬怎么办。
使用 git commit 加 "--amend" 用于修改最后一条 commit。

$ git commit -m "#110 Fix for a real a bug bug"
[master 6665748] Fix for a real a bug bug
 1 file changed, 1 insertion(+), 3 deletions(-)
$ git commit --amend -m "#110 Fix for a real big bug"
[master 6375a9b] Fix for a real big bug
 1 file changed, 1 insertion(+), 3 deletions(-)

再比如提交后发现漏了某些文件, 可以添加修改到暂存区后执行上述命令修正。

注意到上述提交的 SHA 修正后发生改变,说明改变了 git 的历史,所以对于已经推到共享服务器的 commit,修改也可能导致其他合并冲突!

撤销本地提交

场景:修改提交了几个 commit,但是后面发现简直难看或着啥来的,决定撤销掉(这里还在本地,没有推到共享服务器)
找到你想保留的最后一条 commit 的 SHA_last

$ git reset [--mixed] SHA_last

git reset 默认使用模式 --mixed, 操作后,原先提交的 commit 被撤销,但是对应的文件修改依然会保留在工作区。

如果想把修改内容也抛弃,可以使用参数 --hard, 之后,全部都干净了。

重置上面的操作 (抬头..就上面)

场景:我把前面几个 commit 撤销了,而且还使用了 --hard,而后,我发现把有用的提交也不小心撤销了,怎么撤销上面的撤销....

使用 git log 已经无法查看想回退版本的 SHA,但是秉承走过就一定会留下痕迹(浮现老大那轻蔑的眼神,又提了什么傻逼commit然后偷偷回退....)的理念, 方法就是使用git reflog,查看到你提交过所有痕迹,包括已经撤销的(其实git 回定期清除用不到的对象,所以时间太长久,分支改动删除了的,就不要指望记录还在了)。

如列子, 我回退到 83a852b, 发现出错,想跳回到d2ef270,使用 git log 没有记录,使用 git reflog, 可以看到对应 SHA,然后直接 reset 到对应提交。

$ git log --pretty=format:"%h %an %ar : %s"
83a852b luchaodong 20 hours ago : fix uart error with thread & add setup.py
5ec962d luchaodong 12 days ago : add doc 9b16bc4 luchaodong 12 days ago : add py serial rx/tx

$ git reflog 
83a852b HEAD@{0}: reset: moving to 83a852b
d2ef270 HEAD@{1}: commit: test more commit
4e50ae7 HEAD@{2}: commit (amend): #110 Fix for a real big bug
c2e7dbb HEAD@{3}: commit: #110 Fix for a real a bug bug
83a852b HEAD@{4}: commit: fix uart error with thread & add setup.py
5ec962d HEAD@{5}: commit: add doc
9b16bc4 HEAD@{6}: commit (initial): add py serial rx/tx

$ git reset d2ef270
Unstaged changes after reset:
M   pySerial.py

$ git log --pretty=format:"%h %an %ar : %s"
d2ef270 luchaodong 69 seconds ago : test more commit
4e50ae7 luchaodong 2 minutes ago : #110 Fix for a real big bug
83a852b luchaodong 20 hours ago : fix uart error with thread & add setup.py
5ec962d luchaodong 12 days ago : add doc
9b16bc4 luchaodong 12 days ago : add py serial rx/tx

另外也可以记录对应几个提交的 SHA,然后通过git cherry-pick SHA把那几个提交撤销重置。

提交到错误分支的处理方法

场景:开发并提了几个 commit,发现当前在 mater 分支,但是之前的这几个提交是新功能,还不想提交到主分支。
你可以这么做:

$ git branch new_feture            # 保存当前的提交到新分支
$ git reset --hard origin/master   # 恢复主分支
$ git checkout new_feture

保证在最新上更新

场景:几天前你从 master 分支创建 new_fea 分支开发新特性,但是到了今天,master 分支有了其他提交,new_feam 已经滞后master 分支,但是你希望这几天开发的新特性是从今天开始的,而不是滞后那么多天。
当然你可以直接 merge 或者 reset 暂存更新再重新提交,但是这里有一种更加优雅的做法时 rebase

$ git rebase master

上述 rebase 过程如下:

  • 找到当前分支与 master 的共同祖先
  • Reset 到共同祖先位置,暂存 new_fea 后续的提交
  • Fast merge 到 master 末尾,然后再重新 commit 暂存的 new_fea 提交

撤销多个不连续的commit

场景:需要修改到一个早期提交的消息;发现一个早期提交漏了一些修改,想把几个提交合并,让log更加简洁的时候等可以尝试以下方法。

$ git rebase -i SHA_last

使用参数 -i 打开缺省编辑器

我刚测试提交了#1111-1 -- #1111-6 6个提交,输入后会看到如下
按时间先后排下来每个提交:第一列是执行的命令,第二列是SHA, 第三列是提交说明
里面也有详细的使用说明

pick e77c88d #1111-1 test - edit commit
pick 5a1425b #1111-2 test - edit commit
pick b1d7e93 #1111-3 test - edit commit
pick 240d1b7 #1111-4 test - edit commit
pick 2073df0 #1111-5 test - edit commit
pick f61e1ee #1111-6 test - edit commit

# Rebase 83a852b..f61e1ee onto 83a852b
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

执行操作

1 撤销某个commit及其修改 : 在编辑器里面直接删除对应那一行。

2 修改 commit 消息 : 把第一列的 pick 替换为 reword (或者直接用 r); 退出保存后, 会提示重新编辑消息。

3 把两个 commit 合并到一起 : 使用 squash 或 fixup 命令 “向上” 合并

带有这两个命令的 commit 会被合并到它的 前一个(更早的提交) commit 里。

  • squash, Git 会提示我们给新合并的 commit 一个新的 commit 消息;
  • fixup 则会把合并清单里第一个 commit 的消息直接给新合并的 commit 。

4 改变提交顺序 : 修改每一行的顺序来改变对应commit 的顺序。

很容易失败

撤销一个已经有副本的commit

场景:做错事了,而且 push 到服务器,并且被其他人 pull,使用前面的 reset 可能给后续带来冲突。
聚集反物质,把你之前的提交抵消掉,回产生一条新记录,但是内容被重置。

$ git revert SHA_I_dont_want_you

这是 Git 最安全、最基本的撤销场景,因为它并不会改变历史, 然后勇敢地push 到服务器吧。

停止追踪文件

场景 : .gitignore 会阻止 Git 追踪文件的修改,甚至不关注文件是否存在,但这只是针对那些以前从来没有追踪过的文件。一旦有个文件被加入并提交了,Git 就会持续关注该文件的改变。
如果你希望从 Git 的追踪对象中删除那个本应忽略的文件,

$ git rm --cached file_name

Git 会从追踪对象中删除它,但让文件在磁盘上保持原封不动。因为现在它已经被忽略了,你在 git status 里就不会再看见这个文件,也不会再偶然提交该文件的修改了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容