哎呦我去,Git 竟然可以这么用?!!

简介: 用好 Git 很难: 很容易就犯错了,然后想自己弥补犯下的错,简直太难了。

用好 Git 很难: 很容易就犯错了,然后想自己弥补犯下的错,简直太难了。


查阅 Git 文档简直就像是个 “鸡生蛋 蛋生鸡” 的问题,你得知道你要的是啥 ,但如果我知道的话,我还 tm 查个毛文档啊!


所以接下来我会分享一些我遇到过的抓狂的经历,然后用大白话来说说我是如何解决的。


哎呦我去,我刚才好像犯了个大错,能不能给我台时光机啊!?!


git reflog# 你将看到你在 git 上提交的所有改动记录被列# 了出来,而且囊括了所有的分支,和已被删除的# commit 哦!# 每一条记录都有一个类似 HEAD@{index} 的索# 引编号# 找到在犯错前的那个提交记录的索引号,然后执# 行:git reset HEAD@{index}# 哈哈,这就是你要的时光机!


你可以用这个方法来找回那些你不小心删除的东西、恢复一些你对 repo 改动、恢复一次错误的 merge 操作、或者仅仅想退回到你的项目还能正常工作的那一时刻。我经常使用 reflog,在此我要向那些提案添加这个功能的人们表示感谢,太谢谢他们了!


哎呦我去,我刚提交 commit 就发现还有一个小改动需要添加!


# 继续改动你的文件git add . # 或者你可以添加指定的文件git commit --amend --no-edit# 你这次的改动会被添加进最近一次的 commit 中# 警告: 千万别对公共的 commit 做这种操作


这经常发生在我提交了 commit 以后立马发现,妈蛋,我忘了在某个等号后面加空格了。当然,你也可以提交一个新的 commit 然后利用 rebase -i 命令来合并它们,但我觉得我的这种方式比你快 100 万倍。


警告: 你千万不要在已推送的公共分支上做这个 amend 的操作! 只能在你本地 commit 上做这种修改,否则你会把事情搞砸的!


哎呦我去,我要修改我刚刚 commit 提交的信息!


git commit --amend# 按照提示修改信息就行啦


哎呦我去,我不小心把本应在新分支上提交的东西提交到了 master!


# 基于当前 master 新建一个分支git branch some-new-branch-name# 在 master 上删除最近的那次 commitgit reset HEAD~ --hardgit checkout some-new-branch-name# 只有在这个新分支上才有你最近的那次 commit 哦


注意:如果你已将这个 commit 推送到了公共分支,那这波操作就不起作用了。如果你在此之前做了些其他的操作,那你可能需要使用 HEAD@{number-of-commits-back} 来替代 HEAD~。另外,感谢很多人提出了这个我自己都不知道的超棒的解决方法,谢谢大家!


哎呦我去,我把这个 commit 提交错分支了!


# 撤回这次提交,但保留改动的内容git reset HEAD~ --softgit stash# 现在切到正确的那个分支去git checkout name-of-the-correct-branchgit stash popgit add . # 或者你可以添加指定的文件git commit -m "your message here";# 现在你的改动就在正确的分支上啦


很多人建议使用 cherry-pick 来解决这个问题,其实两者都可以,你只要选择自己喜欢的方式就行了。


git checkout name-of-the-correct-branch# 抓取 master 分支上最新的那个 commitgit cherry-pick master# 然后删掉 master 上的那个 commitgit checkout mastergit reset HEAD~ --hard


哎呦我去,我想用 diff 命令看下改动内容,但啥都没看到?!


如果对文件做了改动,但是通过 diff 命令却看不到,那很可能是你执行过 add 命令将文件改动添加到了 暂存区 了。你需要添加下面这个参数。


git diff --staged


这些文件在这里 ¯_(ツ)_/¯ (是的,我知道这是一个 feature 而不是 bug,但它第一次发生在作为初学者的你身上时,真的很让人困惑!)


哎呦我去,我想撤回一个很早以前的 commit!


# 先找到你想撤销的那个 commitgit log# 如果在第一屏没找到你需要的那个 commit,可以用上下# 箭头来滚动显示的内容,找到了以后记下 commit 的# hash 值git revert [刚才记下的那个 hash 值]# git 会自动修改文件来抵消那次 commit 的改动,并创# 建一个新的 commit,你可以根据提示修改这个新 commit# 的信息,或者直接保存就完事了


这样你就不需要用回溯老版本然后再复制粘贴的方式了,那样做太费事了!如果你提交的某个 commit 导致了 bug,你直接用 revert 命令来撤回那次提交就行啦。


你甚至可以恢复单个文件而不是一整个 commit!但那是另一套 git 命令咯...


哎呦我去,我想撤回某一个文件的改动!


# 找到文件改动前的那个 commitgit log# 如果在第一屏没找到你需要的那个 commit,可以用上下# 箭头来滚动显示的内容,找到了以后记下 commit 的# hash 值git checkout [刚才记下的那个 hash 值] -- path/to/file# 改动前的文件会保存到你的暂存区git commit -m "这样就不需要通过复制粘贴来撤回改动啦"


我花了好长好长,真他妈长的时间才搞明白要这么做。说真的,用 checkout -- 来撤回一个文件的改动,这算什么鬼方式啊?! :向 Linus Torvalds 摆出抗议姿势:


去*吧,这些乱七八糟烦人的文件, 我放弃啦。(那些 untracked 的文件)


cd ..sudo rm -r fucking-git-repo-dirgit clone https://some.github.url/fucking-git-repo-dir.gitcd fucking-git-repo-dir


感谢 Eric V. 提供了这个事例,如果对 sudo 的使用有什么的质疑的话,可以去向他提出。


不过说真的,如果你的分支真的这么糟糕的话,你应该使用 "git-approved" 的方法来重置你的 repo,可以试试这么做,但要注意这些操作都是破坏性的,不可逆的!


# 获取远端库最新的状态git fetch origingit checkout mastergit reset --hard origin/master# 删除 untracked 的文件和目录git clean -d --force# 对每一个有问题的分支重复上述 checkout/reset/clean 操作
目录
相关文章
|
安全 Linux 开发工具
狂神聊Git~
狂神聊Git~
|
4月前
|
开发工具 git
【GIT 第二篇章】GIT常用命令
Git常用命令涵盖初始化、状态管理、提交、分支处理、远程操作等关键流程。`git init`启动本地仓库,`git clone`下载远程仓库。通过`git status`和`git diff`检查工作状态与差异。利用`git add`暂存文件,`git commit`保存更改。借助`git branch`、`git checkout`、`git merge`和`git rebase`管理分支。使用`git fetch`、`git pull`和`git push`同步远程仓库。通过`git reset`、`git revert`和`git checkout`实现版本回退。
73 0
|
3月前
|
SQL 缓存 测试技术
代码管理工具之GIT:重新温习一下
代码管理工具之GIT:重新温习一下
|
7月前
|
存储 Linux 开发工具
你再不学Git就来不及了!!!
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。除了项目源代码,你可以对任何类型的文件进行版本控制。
85 1
|
网络安全 项目管理 开发工具
开心档之Git Gitee
开心档之Git Gitee
30 0
|
Unix Linux 开发工具
|
安全 程序员 开发工具
Git奇幻之旅一
今天我要给你讲一个关于Git的故事,希望你能从中学到一些常用的命令。
|
安全 开发工具 git
Git奇幻之旅二
今天我要给你讲一个关于Git的故事,希望你能从中学到一些常用的命令!
|
机器学习/深度学习 存储 开发工具
git奇技淫巧
git奇技淫巧
91 0
|
存储 前端开发 网络安全
Git 的奇技淫巧
Git 是一个 “分布式版本管理工具”,简单的理解版本管理工具:大家在写东西的时候都用过 “回撤” 这个功能,但是回撤只能回撤几步,假如想要找回我三天之前的修改,光用 “回撤” 是找不回来的。而 “版本管理工具” 能记录每次的修改,只要提交到版本仓库,你就可以找到之前任何时刻的状态(文本状态)。
130 0

相关实验场景

更多
下一篇
DataWorks