编程知识 cdmana.com

血泪教训之请不要再轻视Git —— 我在工作中是如何使用 Git 的

到目前为止,我带过三个实习生,每一个都身怀绝技,但是每一个都在git里摔过跤、吃过亏 :

  • 有的处理 git 冲突处理到头秃
  • 有的 git commit message乱糟糟,最后自己都分不清哪个 commit 里是自己想要的代码
  • 有的甚至直接丢失了代码


4565523a17d1d18b6f79fb8e4335eec8.jpeg


毫无疑问,Git 是个非常重要的工具,但是也是被大多数学生、职场新人轻视的一个技能。

今天索性给大家分享我在工作中是如何以最安全最稳健最简单的方式使用 git


设置 git alias

使用 git alias 可以极大地提高效率,我常用的有

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.logl 'log --oneline'

跑完上面的指令,查看 ~/.gitconfig 是否包含以下内容

d534b6b2db13341bf5f74995346fa8d1.png

效果就是

我在命令行里输入 git st 就等同于 git status ,输入 git ci -m "xxx" 等同于 git commit -m "xxx"


最常用的 git 指令 TOP 3

第一个是 git st (即 git status)

我通常在 写完代码后、做任何git操作前、做复杂的git操作的途中(比如 rebase、merge遇到冲突时)和 做完任何git操作后,都会使用 git st 去查看当前的状态 —— 哪些文件还在工作区(还没 git add)、哪些文件还在暂存区(还没 git commit)或者 rebase、merge 的进展等。

充分、及时了解当前的 git 状态可以避免一些误操作


第二个是 git logl (即 git log --oneline )

这个指令可以打印出最近的commit messages,每条message只占一行,使界面更干净、美观。

我通常会在 切换分支的前后,拉取线上分支的前后 使用git logl,它能帮我根据 commit message 确认我当前的分支以及当前分支是否是最新的 (前提是每次 commit 时一定要认真填写 commit message)


第三个是 git ci (即 git commit)

git 之所以使用广泛,是因为它有非常优秀的设计和性能。而其中,commit 是git 设计中的核心。

在日常开发工作中,我通常会在 写完一部分代码后,准备暂时休息前或确认某个功能/bug处理完成后 使用 git add 和 git ci 来保存代码到本地仓库。

记住:只要正确地 commit了,代码就几乎永远不会丢失。(下面有更多对git commit 的讨论)




工作场景一 —— 新任务(开发新特性 / 修bug)

  • git st 查看当前项目的状态,如果有未保存的修改,就git add . 和 git ci -m "xyz" 保存下来
  • 切换到开发主分支,假如项目的主分支叫develop 就使用 git co develop
  • 确保主分支是最新版本 git pull origin develop
  • 创建新分支 git co -b feat-1 (创建一个叫做 feat-1的新分支)
  • 开始写代码
  • 如果当前任务比较复杂,代码量比较多,我通常会多次使用 git add . 和 git ci -m "xxx" 保存当前代码 (记得把 xxx 换成更有意义的文字, 如 git ci -m "init feature-1" )
  • 代码开发结束,整理 commit message 
    首先仍然是用 git st 确保所有代码都commit了(没有就 git add 和 git ci )
    第二步 git logl 查看当前分支下最近的 commit message,如

1d23813 (HEAD -> feat-1) develop feat-1 phase 3
a7e5705 develop feat-1 phase 2
2685240 init feat-1

假设我开发 feat-1 中 commit 了3次,三次的commit message如上所示。


前面说过 commit 是为了防止意外丢失代码,但是在推到远端之前,最好把一次开发的 commit 合并成一个,避免污染远端的 git commit message

因为这个例子中有3个 commit,所以执行 git rebase -i HEAD~3

然后就会看到一个 vim 界面 (不熟悉 vim 基础操作的读者请自行查阅搜索)

03baba68845f83eb217c030a15b0c9f9.png

记住不要动最上面的那行,把下面几行开头的 pick 换成 s , 然后保存

这时会显示另一个 vim 界面

085a27d425885025c71e1502b6cb8179.png

删除所有内容( #开头的可以忽略),然后写一句简短、准确的句子作为这次开发的 commit message,如

c39447b8859700d3102cd1553f3bd11f.png

然后保存

如果成功了就能看见这么一些文字

014504409e62eaea8959818d19891355.png

最后使用 git logl 确认所有这次开发中的 commit message 都被压缩成了一个

(这边只介绍了 git rebase的最简单直接的用法,有兴趣的读者可以去阅读官方文档,了解更详细、高级的用法,如第一次vim界面里使用 f 替代 s 有时候更方便)

  • 最后 git push origin feat-1 把本地仓库推到远端仓库



工作场景二 —— 开发进行一半,需要远端主分支的最新代码

有些时候,你在本地开发某个功能,代码写到一半,某个同事将某些重要代码合进了远端的主分支(如 develop 分支)里。这些重要代码可能是可以极大提升本地开发效率,可能是加入了某些规范检查或者是跟你当前开发相关的代码 —— 总之需要你将那部分代码融入你当前的本地开发环境里。

这种情况下,我会

  • git st 查看当前项目的状态,如果有未保存的修改,就git add . 和 git ci -m "xyz" 保存下来
  • git pull --rebase origin develop 使用这个指令将远端的主分支以 rebase 的形式 “合进”当前分支
  • git logl 查看当前分支下的 commit message 是否符合预期

为什么用 --rebase 呢?

因为这么做,可以让git历史最干净、整洁 —— 所有本地开发的 commit 都会出现在远端主分支里的 commit 之后;并且可以避免额外引入一次 merge 的 commit


工作场景三 —— 希望把某个分支中的某个 commit 对应的代码复制到当前分支

有时我会创建一些实验性的分支,写一些实验性的代码,如果代码不可行,我可以直接废弃掉这个分支,返回原本的开发分支中;如果这些实验性代码可行,我会返回开发分支中,然后把实验性分支的那部分代码“复制”过来,具体操作如下:

  • git st 查看当前项目的状态,如果有未保存的修改,就git add . 和 git ci -m "xyz" 保存下来
  • 假设我们需要的是 feat-1 这个分支的某个 commit ,使用 git logl feat-1 查看最近这个分支的所有 commit 记录,如

d3fba5938ef865b4284979294fd1e853.png

记下对应的 commit 的 hash 值,即开头的7个字符乱码 如上图的 c843c37

  • 使用 git cherry-pick c843c37 将这个 commit 对应的代码复制到当前分支


另外 git cherry-pick 有时还可以用来救场 —— 找回“丢失”的代码,前提是能找到对应的 commit hash 值。




使用git的一些原则

  1. 永远记得 git st 和 git logl 来确认当前分支的状态
  2. 宁愿临时制造一些无用的 commit 来保证代码不会丢失,也不要轻信自己的记忆力
  3. 谨慎(最好能避免)使用 git stash ,极易造成代码丢失
  4. 认真对待、编写每次的 commit message —— 它们能在关键时刻救你一命
  5. 必要的时候可以创建一些临时的分支写实验性的代码,而不是依赖 git reset 撤销 commit —— 大多数人在 git reset 的时候容易犯错误



掌握 git 的方法

今天主要分享了一些实用性的指令和经验,它们可以覆盖大多数普通的开发场景。

但是如果你想彻底掌握git 或者 有能力去处理一些比较复杂的情况,我建议还是能进一步理解 git 的理念(如 为什么 commit 是git的核心? 为什么有 commit 就不怕代码丢失?分支和 commit 是什么关系?有 git commit 为什么还有 git add ?git reset 危险在哪里 ?)

可以阅读我之前写的一篇理解 git 概念的文章,结合本文食用效果更佳 (跳转之前记得先点赞、喜欢、收藏三连!



FreewheelLee:似懂非懂的Git —— 你也只会三招吗?zhuanlan.zhihu.com


最后,欢迎分享你们在使用 git 的时候遭遇的问题或者经验、技巧!


版权声明
本文为[osc_5cok9i01]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4350184/blog/4837712

Scroll to Top