工作中使用 Git 解决问题的场景

更新日期: 2022-07-06阅读: 1.3k标签: git

简单来说,就着七点:

  • 使用 git rebase 让提交记录更加清晰可读
  • 使用 git reflog + git reset 跳到任意 commit
  • 使用 git cherry-pick 获取指定的 commit
  • 使用 git commit --amend 更改提交内容
  • 使用 git revert 回滚某次的提交
  • 使用 git stash 来暂存文件
  • 配置 git alias 提升工作效率

使用 git rebase 让提交记录更加清晰可读

rebase 基本用法

rebase 翻译为变基,它的作用和 merge 相似,用于把一个分支的修改合并到当前分支

如下图所示,经过 rebase 后提交历史的变化情况


不明白单分支的好处,可以在看看知乎的这个问题: Git commits历史是如何做到如此清爽的?

vue 的作者尤雨溪就是说:多用 rebase

具体用法:

git rebase master

git rebase VS git merge

合并分支有两种,即 rebase 、merge

merge 翻译为合并,即 git merge branchname ,即合并分支代码,这种方法会保存每次 commit 的,当你使用 gitk 查看时就发现好几条颜色的线

另一种是 rebase,即去除一系列的提交记录,“复制”它们,然后在另一个地方逐个放下去

所以 rebase 的优势就明了了,它能创造更清晰的提交记录

但 merge 会保留你所有的 commit 的历史时间,当开发人员一多,历史记录就会变得混乱

rebase 的交互模式

在开发中,通常会在一个分支上产生很多无效的提交,这种情况下使用 rebase 的交互模式可以把多次 commit 压缩成一次提交,得到一个干净的提交历史

# 先看提交
git log 
# f9f6f3b commit 3
# 2feb45f commit 2
# 07a3cb6 commit 1
# 我们要修改 2 的话,rebase 到它的下一个 commit,这里是 1
git rebase 07a3cb6 -i
# 然后在打开的对话框里面修改,之后还要一个 rebase continue
git rebase -i <base-commit>
# 或者是 git rebase -i HEAD~2 对最近的两次 commit 进行合并

也有人称之为后悔药功能,即你无论写什么 commit,最后都可以修改,无论提交什么,都可以合并,DIY性强

使用 git reflog + git reset 跳到任意 commit

换个说法叫时光机,即通过查找所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作),通过 reset HEAD 跳到制定 commit

git reflog
#afa2f45 HEAD@{10}: checkout: moving from 今天 to 明天
#4abcda5 HEAD@{11}: commit: 打通1800处仙窍
#de42069 HEAD@{12}: commit: 真言轮经大成
git reset HEAD@{10}
# 或者 git reset --hard afa2f45

如此一来,就回到了 afa2f45 commit 处,熟悉「时间法则」、「时光机」的人都知道,这是回到过去

使用 git cherry-pick 获取指定的 commit

意为“挑拣”提交,和 merge 合并一个分支的所有提交不同,它会获取某个分支的单个提交,并作为一个新的提交接入到当前分支上

这个需要故事背景才容易理解

张三在分支上开发功能,每个功能点提交一次commit,共六个提交六个功能点(分别是 feature1~feature6),再回到第一个提交点,即他使用 git reset --hard feature1 跳转第一个 commit,再此基础上开发一个新功能,即 feature7,那么如果把 feature7 合并到 feature6 上怎么做?

git reflog
# git reflog 查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)
# 找到 feature7 的 commit 4c97ff3
# 回到 feature6 的 commit cd52afc
git reset --hard cd52afc
# 使用 cherry-pick 拿到 feature7 的代码
git cherry-pick 4c97ff3

具体可看小蝌蚪的这篇 小蝌蚪传记:git时光穿梭机--女神的侧颜  来体会一二

简单来说,你的每一次 commit,就是一次记录,可以合并到任意地方。所以开发功能点或者修复bug之类,尽量做到一个功能点一个commit,方便出错时挑拣代码

使用 git commit --amend 更改提交内容

amend 的意思是修正

# 继续改动你的文件
git add . 
git commit --amend --no-edit
# 你这次的改动会被添加进最近一次的 commit 中

合并到上次的commit 中

git commit --amend :弹出让你修改内容

git commit --amend --no-edit :保持上一次的commit内容

PS:假如你的代码已经 push 了的话,要慎用,因为会修改提交历史。

使用 git revert 回滚某次的提交

上文提到一个回滚操作: git reset --hard xxx ,能回到某次的 commit 处从,除此之外,还有一种则是能撤销某次 commit

# 先找到你想撤销的那个 commit hash值
git log
git revert <commit-id>

这种做法会新建一条commit 信息,来撤回之前的修改。

而 git reset 会直接提交记录退回到指定的 commit 上。

所以就个人开发或个人 feature 分支而言,可以使用 git reset 来回滚代码,但在多人协作的集成分支上, git revert 更适合。这样,提交的历史记录不会被抹去,可以安全的进行撤回

使用 git stash 来暂存文件

顾名思义,就是把本地的改动暂存起来

先了解下 git 的四大工作区域

四大工作区域


  • Workspace(工作区):本地电脑所见的文件和目录
  • Index/Stage(暂存区):一般存放在 .git 目录下,当你 git add 改动文件 ,改动的文件就放入在「暂存区」
  • Respository(本地仓库):当你 git clone 地址 ,就将远程仓库克隆到本地仓库。它是存在本地的版本库,其中HEAD指向最新放入仓库的版本。当你执行 git commit ,文件改动就到本地仓库
  • Remote(远程仓库):类似Github、Gitlab、码云等放在代码托管平台

常见的场景是你还在开发一个功能点的时候,突然有个线上 bug 需要你紧急修复,这次你可以git commit 提交到本地仓库,后续通过 git commit --amend 继续在原 commit 上修改内容。但这里还有一种方法,即将代码存在暂存区,等 bug 修复完后,再从暂存区取出

基本命令如下:

git stash # 将本地的改动暂存
git stash save "message" # 执行存储时,添加备注
git stash pop # 应用最近一次暂存,并删除暂存记录
git stash apply #恢复最近的存储,但不会把存储从存储列表中删除,某人使用第一个存储,即 stash@{0},如果要使用其他各,git stash apply stash@{$num}
git stash list # 查看 stash 了哪些存储
git stash clear #删除所有缓存的 stash
git ls-files --stage #查看 index 暂存区

配置 git alias 提升工作效率

主要是为了简化命令,它的基本用法是 git config --global alias.<简化的字符> 原始命令

如下面的例子:

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch

当然,另一种方法是在 .gitconfig 文件中设置

[alias]
st = status -sb
co = checkout
br = branch
mg = merge
ci = commit
ds = diff --staged
dt = difftool
mt = mergetool
last = log -1 HEAD
latest = for-each-ref --sort=-committerdate --format=\"%(committername)@%(refname:short) [%(committerdate:short)] %(contents)\"
ls = log --pretty=format:\"%C(yellow)%h %C(blue)%ad %C(red)%d %C(reset)%s %C(green)[%cn]\" --decorate --date=short
hist = log --pretty=format:\"%C(yellow)%h %C(red)%d %C(reset)%s %C(green)[%an] %C(blue)%ad\" --topo-order --graph --date=short
type = cat-file -t
dump = cat-file -p
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

参考 政采云的配置

除此之外

还有一些不常见却好用的命令

  • gitk :打开git的图形化工具
  • gitjk :撤消您刚刚在git中所做的操作
  • git help -g :展示帮助信息
  • cat .git/HEAD :查看分支文件
  • git fetch --all && git reset --hard origin/master :回到远程仓库的状态

    • 抛弃本地所有的修改,回到远程仓库的状态
  • git push -f origin master :强行获取远程最新代码
原文 https://segmentfault.com/a/1190000042077646

链接: https://fly63.com/article/detial/11864

git入门操作,git命令的基本使用

Git是一个免费的、开放源码的分布式版本控制系统,它能以快速和效率处理从各种各样的项目。(一句话概括,就是分布式版本控制工具)

通过git命令,上传本地文件到git服务器

把本地代码上传到git的方法:步骤一:首先进入需要上传的项目文件夹,通过命令git init初始化,步骤二:将本地文件添加到版本库中,使用命令 git add . 将文件提交到本地的暂存区,步骤三:使用命令git commit将文件提交到本地仓库...

Git忽略规则文件.gitignore_关于.gitignore配置

.gitignore 文件的作用就是告诉git, push的时候忽略指定的文件夹或者文件,例如:vue-cli脚手架创建的项目,push到github上时,不会上传node依赖文件夹,这是因为vue-cli脚手架创建的时候,自动为我们创建了 .gitignroe文件,并且为我们写好了规则。

git从远程仓库克隆dev分支到本地的实现

这篇文章主要介绍git从远程仓库拉取dev分支到本地的实现【gitLab】:初始化一个本地仓库、与远程仓库建立连接 、查看本地是否具有dev分支、在本地创建分支dev并切换到该分支 、dev分支上的内容都拉取到本地

git强制覆盖master分支

在开发中,通常会保持两个分支master分支和develop分支,但是如果因为develop上面迭代太多而没有及时维护master,最后想丢弃master而直接将测试确认过的develop强推到master,该怎么操作呢?因此,做如下总结分享,希望对遇到同样问题的人用帮助。

Git 中 Reset、Revert、Checkout的区别

git reset 、 git checkout 和 git revert 是Git中常用命令。经常傻傻分不清他们之间的区别。最近工作不忙,抽出时间参考了其他文档,对其总结了下。传给 git reset 和 git checkout 的参数决定了它们的作用域。

git workflow

Git与SVN的比较,Gitflow为不同的分支分配一个很明确的角色,并定义分支之间如何和什么时候进行交互。新的功能分支应该从develop分支迁出一个feature分支,新功能开发完成之后再合并回develop分支,常用命令:

项目中常用的git指令

1.新建一个本地分支并切换到新建的那个分支:2.从一个分支切换到另一个分支:3.将代码恢复到最近的一次commit 时候的状态:4.将代码从最近的一次commit的状态恢复到最新的进度:

总结Git 不同情况下撤销和如何回滚

在未进行git push前的所有操作,都是在“本地仓库”中执行的。我们暂且将“本地仓库”的代码还原操作叫做“撤销”,进行git push,即已推送到“远程仓库”中。我们将已被提交到“远程仓库”的代码还原操作叫做“回滚”!注意:对远程仓库做回滚操作是有风险的,需提前做好备份和通知其他团队成员!

.gitignore的使用手册

避免将不必要的文件添加到版本管理系统中,比如前端的node_modules目录,该目录包含大量文件,如果将其添加到版本管理系统中,会使仓库变的庞大,不利于仓库的管理。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!