git checkout -- file 时能否自动备份一下修改过的文件?

2014-02-23 05:07:57 +08:00
 guoqiao
昨天修改一个问题, 由于反复尝试, 一不小心改了同一个文件夹下的好几个文件, 如:

dir/a.py
dir/b.py
dir/c.py
....

但是有一个文件例如c.py是不想提交的.
我执行 git checkout 时手太快, 输入git co -- dir就 enter 了.
这时意识到杯具鸟...
由于修改的代码还是比较多的, 当时真是惊出一身冷汗,心想2个小时的工作没了...
还好我 vim 里的 buffer 还在, 重新逐一保存了下, 都救回来了.

我记得以前用别的 VCS, 每次你恢复文件的时候, 会创建一个c.py.orig 之类的备份.
在 git 下, 有类似的功能吗? 或者, 大家用 git 时是如何避免我这样的杯具的?
6721 次点击
所在节点    程序员
27 条回复
jabbany
2014-02-23 05:10:36 +08:00
先 stash 一下?
alexrezit
2014-02-23 08:00:06 +08:00
git stash
wwqgtxx
2014-02-23 08:16:46 +08:00
每次都用git-gui,提交前还能看一下diff,避免绝大多数问题
guoqiao
2014-02-23 10:36:26 +08:00
@alexrezit 使用 statsh 的场景是暂时中断当前的工作,回到代码库的最新版,然后事后还能回到工作版本. 跟我这里的场景有点不一样. 我并不是要回到最新版. 我是希望能自动备份下,避免出错. 也就是我 git checkout -- c.py的时候,能自动给我建一个c.py.orig
guoqiao
2014-02-23 10:38:11 +08:00
@wwqgtxx 用 terminal 用惯了, 不想多开一个程序. 本质上, 你用 gui,如果 checkout 时不小心勾选了全部文件, 也会有一样的问题. 只是稍微直观了一点而已.
xcatliu
2014-02-23 10:40:58 +08:00
任何 git add 过的文件,都会在 git 历史中保留此次 hash 值,找到即可 reset 恢复文件。
具体怎么找到可以用 git reflog 或者 git log -g 找到历史记录。
guoqiao
2014-02-23 10:42:02 +08:00
@xcatliu 没提交过的修改也行??
xcatliu
2014-02-23 10:45:05 +08:00
@guoqiao 没提交过的也可以,只要 add 就会在 git 中留下记录。
如果 add 都没有过就无法使用 git 恢复了。。
guoqiao
2014-02-23 10:47:01 +08:00
@xcatliu 这么说, 我每改动一下文件, git 都会给我备份下? 要不要这么辛苦...
G_virus
2014-02-23 10:53:31 +08:00
只要 add 过的文件就可以用 fsck 找回,以前在 stackoverflow 上曾经回答过一个这样的问题。

http://stackoverflow.com/questions/14475003/recover-files-after-git-rm-rf/14475432#14475432

不过lz的情况是 add 都没有 add 过的话,那确实没办法了……因为没有任何相关的信息保存到 git 里。
xcatliu
2014-02-23 10:56:13 +08:00
@guoqiao 修正一下,git reflog 或者 git log -g 好像是恢复 commit 的,add 过的怎么恢复不记得了。。
Mutoo
2014-02-23 10:57:02 +08:00
看了一下 git 的 client-side hooks 好像也没有能满足你的要求的。只有一个 post-checkout 是在 checkout 之后。

我想到一个很麻烦的方法就是你在本地有两个工作目录,一个用来 commit 一个用来 checkout,中间用 rsync 同步,可以用 rsync 的 --backup 实现备份
9hills
2014-02-23 11:09:48 +08:00
@guoqiao 必须是在stage区域的才能通过git fsck找回。

话说你这种使用方法就不对:有一个文件例如c.py是不想提交的.

如果有一个文件不想提交,请单开分支commit或者加到gitignore中忽略掉。而不是连stage区域都不放,这个丢了神仙也没办法的。
9hills
2014-02-23 11:11:05 +08:00
git的精髓是一次只做一件事,如果一次要做好几件事,比如既要改bug又要开发新feature,请善用分支功能。每个分支只做一件事
guoqiao
2014-02-23 11:29:02 +08:00
@9hills
"如果有一个文件不想提交,请单开分支commit或者加到gitignore中忽略掉。而不是连stage区域都不放,这个丢了神仙也没办法的。"

我是调试时在那个文件里加了一行 print xxx, 莫非为了这个我要开分支...
加 ignore 也不对, 我不是要 ignore, 我只是要撤销本次的修改.
guoqiao
2014-02-23 11:31:41 +08:00
@9hills 我知道道理如此, 这不止是 git 的精髓, 这也是 Unix 的精髓.
但是, 这种道理看你怎么想了.
比如, 如果你用过 hg, 你就知道 git 的 pull 其实做了两件事, 对应到 hg 里是:
hg pull & hg update

显然 hg 的做法更严谨, 一次一件事. 但是你绝对会为这件事很恼火.
guoqiao
2014-02-23 11:35:51 +08:00
@Mutoo 还是省省吧, 为了解决一个小问题, 这会耽误你更多时间, 然后, 带来更多问题...
guoqiao
2014-02-23 11:43:31 +08:00
其实我一直想说, git 的命令行接口简直是反人类, 就没几个直观的.
从回答也能看出, 大家对 git 的理解五花八门, 人人都觉得自己的workflow是对的.
hg 比 git 要易用太多, 只可惜大势已去...
FrankFang128
2014-02-23 11:47:38 +08:00
用 JetBrain 的IDE,有本地历史!
9hills
2014-02-23 11:56:44 +08:00
@guoqiao 如果是print xxx的话,被清理掉也没啥损失吧。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/101419

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX