掌握这5个Git命令,提升你的版本控制效率

在现代软件开发中,Git已成为版本控制的标配工具。然而,许多开发者对Git的掌握仅限于基本操作,如保存、拉取和推送代码。当面临复杂的commit管理挑战时,他们往往感到困惑,甚至采用笨拙的解决方案。为了帮助大家突破这一瓶颈,本文将分享一系列我在实际开发中验证过的高效Git命令。

这些命令不仅能够显著提升你的工作效率,还能助你在面对复杂问题时游刃有余。文章将详细解释每个命令的用途、适用场景,并提供详细的操作指导。目标是让每一位读者在阅读完本文后,能够立即上手实践,从而优化你的代码管理流程。

1、stash 存储临时代码

在使用Git进行版本控制时,我们经常会遇到需要临时保存当前工作进度,以便切换到其他分支或进行其他操作的情况。这时,git stash命令就显得尤为重要。它允许你将工作目录中的未提交更改临时存储起来,同时恢复工作目录至最后一次提交的状态,保持工作空间的整洁。

简而言之,git stash命令能够实现以下功能:

  1. 保存当前工作目录中的所有本地修改。
  2. 清除工作目录,使其与最新的提交状态一致。
  3. 让你能够自由切换分支或进行其他操作,而不必担心未完成的工作被干扰。

应用场景

在软件开发过程中,我们经常会遇到这样的紧急情况:你正在feature分支上如火如荼地开发新功能,突然产品经理通知你,线上出现了一个必须立即修复的bug。这时,你需要迅速切换到master分支进行修复,却发现因为当前工作区有未提交的更改,无法直接切换分支。

面对这种情况,你可能会匆忙地将更改提交,甚至在commit信息中随意写上“暂存代码”,导致项目的历史记录中留下了不清晰的提交记录。

为了避免这种尴尬局面,我们可以采取以下步骤来优雅地处理这种开发中断:

  1. 使用git stash命令,将当前工作区的更改临时保存起来,这样你的工作区就会变得干净,可以立即切换到master分支。
  2. master分支上修复bug,并确保测试通过后,提交修复。
  3. 修复完成后,切换回feature分支,并使用git stash popgit stash apply命令恢复之前保存的工作进度。
  4. 继续你的功能开发,确保commit信息清晰、准确,以维护项目的历史记录的清晰度。

相关命令

# 保存当前未commit的代码
git stash

# 保存当前未commit的代码并添加备注
git stash save "备注的内容"

# 列出stash的所有记录
git stash list

# 删除stash的所有记录
git stash clear

# 应用最近一次的stash
git stash apply

# 应用最近一次的stash,随后删除该记录
git stash pop

# 删除最近的一次stash
git stash drop

当有多条 stash,可以指定操作stash,首先使用stash list 列出所有记录:

$ git stash list
stash@{0}: WIP on ...
stash@{1}: WIP on ...
stash@{2}: On ...

应用第二条记录:

$ git stash apply stash@{1}

2、reset-soft  软回溯

在使用Git进行版本控制时,git reset命令是管理提交历史和更改的关键工具。它允许你撤销已提交的更改,或者重新安排提交顺序,而不直接修改工作树或索引文件。以下是git reset命令的两种常用模式:

  1. git reset --hard:这种模式会将HEAD指针强制移动到指定的提交,并彻底清除所有后续的提交记录。同时,它会重置工作树和索引,使其与指定提交的状态完全一致。这种操作是不可逆的,因此在执行前需要谨慎考虑。

  2. git reset --soft:与--hard选项相比,--soft选项则更为温和。它同样会将HEAD指针移动到指定的提交,但不会改变工作树和索引。所有被回退的提交的更改内容仍然保留在暂存区中,等待下一次提交。这种方式允许你在不丢失任何更改的情况下,重新组织提交历史。

在紧急情况下,如需要快速回退到某个稳定状态,git reset --hard可以迅速解决问题。然而,在日常开发中,git reset --soft提供了更多的灵活性,允许你在不丢失工作进度的情况下,调整提交的顺序或撤销错误的提交。

应用场景

应用场景1:有时候手滑不小心把不该提交的内容 commit 了,这时想改回来,只能再 commit 一次,又多一条“黑历史”。

应用场景2:规范些的团队,一般对于 commit 的内容要求职责明确,颗粒度要细,便于后续出现问题排查。本来属于两块不同功能的修改,一起 commit 上去,这种就属于不规范。这次恰好又手滑了,一次性 commit 上去

命令使用

学会reset --soft之后,你只需要:

# 恢复最近一次 commit
git reset --soft HEAD^

reset --soft相当于后悔药,给你重新改过的机会。对于上面的场景,就可以再次修改重新提交,保持干净的 commit 记录。

以上说的是还未 push 的commit。对于已经 push 的 commit,也可以使用该命令,不过再次 push 时,由于远程分支和本地分支有差异,需要强制推送git push -f来覆盖被 reset 的 commit。

还有一点需要注意,在reset --soft指定 commit 号时,会将该 commit 到最近一次 commit 的所有修改内容全部恢复,而不是只针对该 commit。

举个例子:

commit 记录有 c、b、a。

图片

reset 到 a。

git reset --soft 1a900ac29eba73ce817bf959f82ffcb0bfa38f75

此时的 HEAD 到了 a,而 b、c 的修改内容都回到了暂存区。

图片

3、cherry-pick  复制commit

给定一个或多个现有提交,应用每个提交引入的更改,为每个提交记录一个新的提交。这需要您的工作树清洁(没有从头提交的修改)。

将已经提交的 commit,复制出新的 commit 应用到分支里

应用场景

commit 都提交了,为什么还要复制新的出来?

应用场景1:有时候版本的一些优化需求开发到一半,可能其中某一个开发完的需求要临时上,或者某些原因导致待开发的需求卡住了已开发完成的需求上线。这时候就需要把 commit 抽出来,单独处理。

应用场景2:有时候开发分支中的代码记录被污染了,导致开发分支合到线上分支有问题,这时就需要拉一条干净的开发分支,再从旧的开发分支中,把 commit 复制到新分支。

命令使用

复制单个

现在有一条feature分支,commit 记录如下:

图片

需要把 b 复制到另一个分支,首先把 commitHash 复制下来,然后切到 master 分支。

图片

当前 master 最新的记录是 a,使用cherry-pick把 b 应用到当前分支。

图片

完成后看下最新的 log,b 已经应用到 master,作为最新的 commit 了。可以看到 commitHash 和之前的不一样,但是提交时间还是保留之前的。

复制多个

以上是单个 commit 的复制,下面再来看看 cherry-pick 多个 commit 要如何操作。

  • 一次转移多个提交:

git cherry-pick commit1 commit2

上面的命令将 commit1 和 commit2 两个提交应用到当前分支。

  • 多个连续的commit,也可区间复制:

git cherry-pick commit1^..commit2

上面的命令将 commit1 到 commit2 这个区间的 commit 都应用到当前分支(包含commit1、commit2),commit1 是最早的提交。

cherry-pick 代码冲突

cherry-pick多个commit时,可能会遇到代码冲突,这时cherry-pick会停下来,让用户决定如何继续操作。下面看看怎么解决这种场景。

图片

还是 feature 分支,现在需要把 c、d、e 都复制到 master 分支上。先把起点c和终点e的 commitHash 记下来。

图片

切到 master 分支,使用区间的cherry-pick。可以看到 c 被成功复制,当进行到 d 时,发现代码冲突,cherry-pick中断了。这时需要解决代码冲突,重新提交到暂存区。

图片

然后使用cherry-pick --continuecherry-pick继续进行下去。最后 e 也被复制进来,整个流程就完成了。

以上是完整的流程,但有时候可能需要在代码冲突后,放弃或者退出流程:

  • 放弃 cherry-pick:

git cherry-pick --abort

回到操作前的样子,就像什么都没发生过。

  • 退出 cherry-pick:

git cherry-pick --quit

不回到操作前的样子。即保留已经cherry-pick成功的 commit,并退出cherry-pick流程。

4、revert  撤销commit的修改内容

给定一个或多个现有提交,恢复相关提交引入的更改,并记录一些这些更改的新提交。这就要求你的工作树是干净的(没有来自头部的修改)。

将现有的提交还原,恢复提交的内容,并生成一条还原记录。

应用场景

应用场景:有一天测试突然跟你说,你开发上线的功能有问题,需要马上撤回,否则会影响到系统使用。这时可能会想到用 reset 回退,可是你看了看分支上最新的提交还有其他同事的代码,用 reset 会把这部分代码也撤回了。由于情况紧急,又想不到好方法,还是任性的使用 reset,然后再让同事把他的代码合一遍(同事听到想打人),于是你的技术形象在同事眼里一落千丈。

命令使用

revert 普通提交

学会 revert 之后,立马就可以拯救这种尴尬的情况。

现在 master 记录如下:

图片

git revert 21dcd937fe555f58841b17466a99118deb489212

revert 掉自己提交的 commit。

图片

因为 revert 会生成一条新的提交记录,这时会让你编辑提交信息,编辑完后 :wq 保存退出就好了。

图片

再来看下最新的 log,生成了一条 revert 记录,虽然自己之前的提交记录还是会保留着,但你修改的代码内容已经被撤回了。

revert 合并提交

在 git 的 commit 记录里,还有一种类型是合并提交,想要 revert 合并提交,使用上会有些不一样。

图片

现在的 master 分支里多了条合并提交。

图片

使用刚刚同样的 revert 方法,会发现命令行报错了。为什么会这样?在官方文档中有解释。

通常无法 revert 合并,因为您不知道合并的哪一侧应被视为主线。此选项指定主线的父编号(从1开始),并允许 revert 反转相对于指定父编号的更改

我的理解是因为合并提交是两条分支的交集节点,而 git 不知道需要撤销的哪一条分支,需要添加参数 -m 指定主线分支,保留主线分支的代码,另一条则被撤销。

-m 后面要跟一个 parent number 标识出"主线",一般使用 1 保留主分支代码。

git revert -m 1 <commitHash>

revert 合并提交后,再次合并分支会失效

还是上面的场景,在 master 分支 revert 合并提交后,然后切到 feature 分支修复好 bug,再合并到 master 分支时,会发现之前被 revert 的修改内容没有重新合并进来。

因为使用 revert 后, feature 分支的 commit 还是会保留在 master 分支的记录中,当你再次合并进去时,git 判断有相同的 commitHash,就忽略了相关 commit 修改的内容。

这时就需要 revert 掉之前 revert 的合并提交,有点拗口,接下来看操作吧。

图片

现在 master 的记录是这样的。

图片

再次使用 revert,之前被 revert 的修改内容就又回来了。

5、reflog  记录commit的历史操作

此命令管理重录中记录的信息。

如果说reset --soft是后悔药,那 reflog 就是强力后悔药。它记录了所有的 commit 操作记录,便于错误操作后找回记录。

应用场景

应用场景:某天你眼花,发现自己在其他人分支提交了代码还推到远程分支,这时因为分支只有你的最新提交,就想着使用reset --hard,结果紧张不小心记错了 commitHash,reset 过头,把同事的 commit 搞没了。没办法,reset --hard是强制回退的,找不到 commitHash 了,只能让同事从本地分支再推一次(同事瞬间拳头就硬了,怎么又是你)。于是,你的技术形象又一落千丈。

命令使用

图片

分支记录如上,想要 reset 到 b。

图片

误操作 reset 过头,b 没了,最新的只剩下 a。

图片

这时用git reflog查看历史记录,把错误提交的那次 commitHash 记下。

图片

再次 reset 回去,就会发现 b 回来了。

设置 Git 短命令

对我这种喜欢敲命令而不用图形化工具的爱好者来说,设置短命令可以很好的提高效率。下面介绍两种设置短命令的方式。

方式一

git config --global alias.ps push

方式二

打开全局配置文件

vim ~/.gitconfig

写入内容

[alias] 
        co = checkout
        ps = push
        pl = pull
        mer = merge --no-ff
        cp = cherry-pick

使用

# 等同于 git cherry-pick <commitHash>
git cp <commitHash>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值