Git命令行开发指南

目录

前言

做为长期使用Ubuntu的开发者,在命令行下开发已经变成一种习惯。我们在日常开发中使用Git来管理我们的源代码。仅以这篇文章记录常见的Git开发流程可能会遇到的场景。

命令行开发

在进行配置前,可以按照官方的教程进行安装 Git

基本配置

我们推荐使用SSH Key方式,实现免密拉取代码。首先你需要生成秘钥,将生成的id_rsa.pub复制粘贴到你的SSH Key认证页面里。以Ubuntu为例:

# 使用ssh-keygen生成秘钥
ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/geekwho/.ssh/id_rsa):
Created directory '/home/geekwho/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/geekwho/.ssh/id_rsa.
Your public key has been saved in /home/geekwho/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:71YiyxIrW0X88/LbPEzB2MQs6ruzCIEXMfE4pMgaryA geekwho@xbc.me
The key's randomart image is:
+---[RSA 2048]----+
|      =.     o   |
| . . o *    . +  |
|. o . + +  . *   |
| +   . + .. . +  |
|E . . o S.o    . |
|o.   ..o..oo. .  |
|.     o+ oo+.o   |
|    ..o.oo+o oo  |
|    .o ...++o.o. |
+----[SHA256]-----+

配置提交开发者信息:

git config --global user.name "GeekWho"
git config --global user.email geekwho@xbc.me
git config --global core.editor vim
git config --global core.filemode false
配置别名,减少输入命令的长度:
#alias 创建命令别名
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.cp cherry-pick
git config --global alias.st status
git config --global alias.br branch
git config --global alias.r rebase
git config --global alias.ri rebase -i
git config --global alias.l '!git --no-pager log --graph --pretty=format:"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset" --abbrev-commit --date=relative'
git config --global alias.lg 'log --graph --pretty=format:"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset" --abbrev-commit --date=relative'

这里,我以日常的版本开发为例,使用Git进行源代码管理的操作。

我假设你有一个master(主干分支)、feature-1.0.0(版本分支)、feature-geekwho(个人开发分支)。最简单的开发流程如下:

  1. 日常开发在个人开发分支feature-geekwho。
  2. 开发完成后,合并到feature-1.0.0分支。
  3. feature-1.0.0发布上线后,合并到master。

日常操作可能会有下列这些场景:

  1. 拉取代码:拉取feature-1.0.0分支最新的代码
  2. 切换分支:从分支feature-geekwho切换到feature-1.0.0
  3. 合并代码:个人开发分支feature-geekwho合并最新的feature-1.0.0
  4. 整理代码:整理个人开发分支feature-geekwho的提交

拉取代码

# 使用git clone 命名拉取代码
git clone git@github.com:geekwho11/learn.php.xbcme.git
# 默认拉取到本地是master分支
cd learn.php.xbcme
# 切换到feature-1.0.0分支
git checkout feature-1.0.0
# 拉取远端的更新
git pull --rebase origin feature-1.0.0

切换分支

开发中经常会遇到依赖他人的接口,需要合并代码。我们假设当前正在feature-geekwho正在愉快地开发,但突然我们希望合并feature-geekwho的代码来解决依赖问题。这时候你可以这样操作:

# 查看当前分支的状态
git status
# 如果什么改动都没有,那么会显示
➜  learn.php.xbcme git:(feature-geekwho) git st
位于分支 master
无文件要提交,干净的工作区
# 没有改动,直接进行切换即可
git checkout feature-1.0.0

但大部分情况,我们会遇到这种情况:

➜  learn.php.xbcme git:(feature-geekwho) ✗ git st
位于分支 master
您的分支与上游分支 'origin/feature-geekwho' 一致。

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
  README.md

提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

这时,你有2个选择:

  1. 把当前的改动进行提交,然后切换到分支feature-1.0.0
git add README.md
git commit -m "* commit log"
git checkout feature-1.0.0
  1. 利用git stash命令暂存你的改动
# stash 可以暂存多个改动
➜  learn.php.xbcme git:(feature-geekwho) ✗ git stash
保存工作目录和索引状态 WIP on feature-geekwho: c02bf01 * 一些改动
git checkout feature-1.0.0
# 做了一些操作,想要找回自己的修改
git checkout feature-geekwho
# 查看暂存列表
git stash list

stash@{0}: WIP on feature-geekwho: c02bf01 * 一些改动
# 由于stash是由栈实现,直接"弹出"修改
git stash pop
➜  learn.php.xbcme git:(feature-geekwho) git stash pop
位于分支 learn.php.xbcme
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
  修改:     README.md

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
丢弃了 refs/stash@{0}(7c35b45658e3c20586d6cf8c526f919e106fbf5d)
# 看下,你的代码是不是又回来了?

合并分支代码

你有2个方式可以合并分支feature-1.0.0的代码:

  1. 使用git merge方式合并feature-1.0.0的更新到个人开发分支 feature-geekwho
# 切换到版本分支
git checkout feature-1.0.0
# 拉取远端分支的更新
git pull --rebase origin feature-1.0.0
# 切换到自己的开发分支
git checkout feature-geekwho
# 在feature-1.0.0的基础上进行合并
git merge feature-1.0.0

Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)
# 出现上面的提示,代表合并成功,并生成一个新提交标识。
  1. 你还可以使用git rebase 减少这个新提交标识,就像你是在feature-1.0.0上进行提交一样。
# 切换到版本分支
git checkout feature-1.0.0
# 拉取远端分支的更新
git pull --rebase origin feature-1.0.0
# 切换到自己的开发分支
git checkout feature-geekwho
# 在feature-1.0.0的基础上进行rebase
git rebase feature-1.0.0
First, rewinding head to replay your work on top of it...
Applying: 一些提交

变基与合并最大的区别:合并会生成一个新的提交标识,而变基就像你在feature-1.0.0进行一系列提交,没有生成新的提交标识。官方文档有很好的图例解释这两个命令的异同。

整理提交

在开发中,可能会有很多个提交,很多时候,这些提交都是临时无意义的,所以我们需要整理自己的提交,像下面这类:

# git log 查看提交

* 调试功能a x7 commitid7 author1 2019-06-15 17:00:07
* 调试功能a x6 commitid6 author1 2019-06-15 17:00:06
* 调试功能a x5 commitid5 author1 2019-06-15 17:00:07
* 调试功能a x4 commitid4 author1 2019-06-15 17:00:06
* 调试功能a x3 commitid3 author1 2019-06-15 17:00:07
* 调试功能a x2 commitid2 author1 2019-06-15 17:00:06
* 添加功能a    commitid1 author1 2019-06-15 17:00:07
# 切换到开发分支
git checkout feature-geekwho
# 重置到commitid1这次的提交
git reset commitid1
# 重新添加文件
git add .
# 再次commit,并改写当前的提交
git commit -m "+ 添加功能a,完成测试,参考下面的注释模板" --amend
# 这样你就得到一个经过整理的提交了
* + 添加功能a,完成测试,参考下面的注释模板    commitid1 author1 2019-06-15 17:00:00
# 加--amend参数作用是改写commitid1的提交
# 如果直接git commit -m "+ 添加功能a,完成测试,参考下面的注释模板",你会得到2个提交
* + 添加功能a,完成测试,参考下面的注释模板    commitid2 author1 2019-06-15 18:00:00
* 添加功能a    commitid1 author1 2019-06-15 17:00:07
# 直接推送到远端分支
git push -f origin feature-geekwho

总结

文章总结了在日常开发过程经常会遇到的场景,整理相关Git命令,方便遇到问题对号入座,找到最终的解决方案。如果想要熟练运用Git的话,还是需要花费时间去阅读官方的文档,学习Git的命令相关原理,这样才能有效提升开发效率。

参考链接

  1. Git 官方文档
  2. 连猴子都能懂的Git入门指南
  3. Pro Git