git 常用命令详解(下)

简介: git 常用命令详解(下)

git rebase



a31088795b244791b8de75c97294b4e2_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

我们还是看这个图,本来 topic 分支是从 E 打出来的,如果想改成 从 G 打出来,可以这样写

git rebase master topic

1c32f8acdb4448db8bed6f5fb704b530_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

一般情况下,我们是在 topic 分支执行这个命令,可以省略后面的 topic

git rebase master
复制代码

除了变基, rebase 最好用的功能是修改未发布分支的历史。

修改最近三条提交

rebase -i head~3
复制代码

弹出一个对话框 ,最上面显示的是对三条信息的处理意见。注意是正序显示了。默认为采用,保持原样。

pick a582932 第一次提交
pick 4665a16 第二次提交
pick 31b2f1f 第三次提交
复制代码

现在删除第一次提交,修改第二次提交,保留第三次提交

drop a582932 第一次提交
edit 4665a16 第二次提交
pick 31b2f1f 第三次提交
复制代码

修改完成后,保存退出。rebase 停在第二次提交,你可以做修改,然后执行 git commit --amend

如果一切满意,执行 git rebase --continue,最后显示成功。

有这几种常用的命令

  • pick  : 保持不变
  • reword  = 只修改 message,也就是只修改提交信息。
  • edit  = 停在这个提交,修改, 执行 git commit --amend,提交修改。
  • squash  = 合并到前一个提交。会弹出一个对话框,默认显示所有合并 commit 的提交信息,你可以直接保存退出,也可以编辑提交信息,直接满意。所有合并的提交会被删除,用一个新的提交代替。
  • fixup [-C | -c]  = 如果不带参数,和squash 一样,只是不弹出对话框,直接采用前一个提交的 message 生成新的提交。如果加  -c 参数 ,和 squash 的形为差不多一样。
  • exec  = 不处理 commit,只是单纯的执行 shell 命令。比如
exec list
复制代码
  • 会执行 list 命令
  • break = 停止执行 (恢复执行 'git rebase --continue')
  • drop  = remove commit

注意 rebase 只应该修改未发布的 commit

git 分支

分支是并行开发的基础。分支名称的本质是对分支最后一个提交的引用。分支有多个,但 HEAD 只有一个,可以认为 HEAD 是"current branch"(当下的分支)。当你用git switch切换分支的时候,HEAD 重新指向新的分支。

分支是 git 的杀手级应用。Git 处理分支的方式可谓是难以置信的轻量,git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。分支会涉及很多常用 git 命令,我们在这里一起讲。

分支的名称是一个引用,指向支持的最后一个提交节点。分支就是从父分支开始的第一个节点,到最后一个节点的所有 节点的集合。

新建 git 分支

当你新建仓库的时候,会默认建立 master 分支。

git init test 
 git init
复制代码

两种写法都可以。不同的是,git init test 会在当前目录下新建 test 文件夹,git init 会在当前目录初始化 git。

至于说建议用 main 而不是 master,其实就是名字,名字本无含意,在 git 中就是分支的名字而已,是看名字的人读出了所谓含意。如果在意名字,也是可以修改的。

git init -b main   用 -b 指定初始化的分支为 main 
复制代码

也可以在全局指定,后面就不用 -b 指定了。

git config --global init.defaultBranch main
复制代码

初始化完成后,新建其它的分支有三种方法。

git checkout -b dev
git switch -b dev
git branch dev
复制代码

这三种方法都可以新建 dev 分支。不同的是前两种新建并转到新分支,最后一种只新建分支不跳转。

既然 git checkout -b devgit switch -b dev效果完全一样,为什么弄出两个来?开始都是用 git checkout -b,后来觉得用git checkout -b不够清晰,checkout被赋予了太多职责,所以增加了 switch 命令。

git cherry-pick

为什么要用 cherry-pick?

不适合 merge 的场景就可以考虑 cherry-pick。

试想下面这些场景

  1. 只想同步分支的部分提交。两个分支是两上完全独立的 feature,不适合 merge。
  2. 不想过早的同步分支。

下面举几个例子。 dev 为 分支 ,A、B 为 commit。

git cherry-pick dev   将 dev 分支的最近一次提交,转移到当前分支。
git cherry-pick A 可以转移有权访问的任意分支的任意提交。
git cherry-pick A B 一次可以同步多个提交   
转移从 A 到 B 的所有提交,不包含 提交 A。提交 A 必须早于提交 B,否则命令将失败,但不会报错。
git cherry-pick A..B 
包含提交 A 
git cherry-pick A^..B   
复制代码

如果没有冲突会在当前分支形成一个新的提交,提交的内容和 message 完全一样,只是 hash( commit id) 值不一样。

如果有冲突,解决冲突的方法前面在  git checkout 那一节已经说过,解决的方法是一样的,最后用 git cherry-pick --contine,如果想撤销用 git cherry-pic --abort

git patch

为什么要用 patch?

不适合 merge,也不方便 cherry-pick 的场景,可以考虑 patch。

试想下面这些场景

  1. 两个不同的 git 库,其中的某段代码需要同步。
  2. 有些修改会影响所有开发者,但你想做这个修改,来验证一些东西。你需要另一个开发配合,需要把这个修改同步给他。直接 copy 是个办法,但如果修改较多,容易出错,用 patch 比较合适。

虽然 check-pick 也可以同步不同的库,但实操的时候,因为权限或安全问题,不大方便联网同步。

patch 方案

pach 有两种方案,diff 和 format-patch。

diff 仅保留了文件重 A 状态变成 B 状态的差别,而不会保留 commit 记录消息等信息,diff可以多个commit生成单个patch。用 git apply 应用补丁。

format-patch 完整保留了每次提交的完成信息,每个commit都生成一个patch文件。用 git am 应用 补丁。

检查都是用 git apply --check。查看 都是 git applay -stat

diff 生成 patch,apply 应用patch

制作 patch

git diff >fix.patch  
git diff 38d8e02 >fix.patch 相当于 
git diff 38d8e02 HEAD >fix.patch
复制代码

总之,diff 的结果都可以制作 patch。

应用 patch

git apply --check fix.patch
git apply fix.patch
复制代码

format-patch 制作 patch ,am 应用 patch

git format-patch -2               用最近的两次提交制作 patch 
git format-patch commitId         某次提交以后的所有patch,不包括本次提交
git format-patch --root commitId  从第一次提交到指定提交的所有 patch
git format-patch -o patch -2      输出 patch 文件到 patch 文件夹      
复制代码

format-patch 制作的 patch 是一个提交一个文件,正序排列。

0001-第一次提交.patch
0002-第二次提交.patch
复制代码

应用提交

git apply --check *.patch
git am *.patch
复制代码

git stash

stash 的英文原意是 贮藏。git stash 的功能就是把当前工作区的内容存起来。和提交到暂存区不同,git stash贮藏的内容不受分支切换的影响。

应用场景

  1. 开发了一阵,发现分支错了。这时最好的文案就是 git stash save ,切到新分支后 git stash pop
  2. 开发到一半,有一个紧急的 bug 要 fix,这时提交会造成无效的提交记录。可以先 git stash save,切换分支修复 bug,再切回来  git stash pop

注意:没有被 add 过的文件不会被 stash 起来,如果想把这些文件也一起 stash,可以加上 -u 参数,它是 --include-untracked 的简写, git stash -u。

非常感谢你能读到这里。如果你都掌握了,你现在已经掌握了足够的知识了,为了能运用自由,还需要融汇贯通,学而不思则罔。下面举几个实战的例子

git 命令实战

你在分支 A,一个同事在分支 B fix 了一个bug。你不方便 merge  分支B,只想更新这个 fix bug 的提交。

最先想到的是 cherry-pick,但还有两个办法,git restore,和 patch。相比较来说,如果 fix 已经提交到远程,cherry-pick 是最佳的,git restore 也可以,但是还得提交一次。如果网络不通,那只能用 patch了。


修改上次提交的 message 可以用 git commit --amend,那如果是修改上上次提交的 message 呢?

方案一 reset + chery-pick

git log --oneline
081b00b (HEAD -> master) 第二次提交
451ddbc                  第一次提交
复制代码

如果要修改第一次提交的提交信息,需要先退回到第一次提交,再修改提交信息

git reset --hard HEAD^
git commit --amend -m '第一次提交补充'
复制代码

修改完第一次提交的信息,我们用第二条提交的 commid id 恢复第二条信息

git cherry-pick 081b00b
复制代码

也许你会问,直接 把 HEAD reset 到 081b00b 可以吗?答案是不可以。因为执行 cherry-pick 后,虽然内容和 message 都一样,但这本质上却是一个新的提交。无法从这个提交回到 081b00b。

方案二 rebase

用 rebase 有一个前提,提交次数 >2

git rebase -i HEAD~2 
复制代码

在 dev 分支上开发完了,发现提交记录太多太乱了,提交主干的时候想合成一个提交,将来查的时候也好查。

git merge-base master dev
输出:caa12ecabf18b0b7247f07481b01946f8b548d94
git reset --soft caa12ecabf18b0b7247f07481b01946f8b548d94
git commit 'feat:登录'
复制代码

示例把所有修改合成一个提交,也可以分成几次提交。如果那样的话,需要用 --mixed 参数 ,把暂存区也还原。


用分支开发的时候,合并到主干可能会产生分叉。如果不想分叉呢?也是可以做到的。

场景一 从master创建分支 dev 后,master 没有修改,合并的时候,不会有分叉。

场景二 从master创建分支 dev 后,master 有修改,合并的时候,有分叉,为了避免出现分叉,不直接在 master 分支执行 merge,而是在 dev 分支 执行 rebase ,然后在 master 再执行 merge。

git switch dev 
git rebase master
git switch master
git merge dev
复制代码

这样在 master 分支上就不会有分叉了。

rebase 的过程相当于把 dev的提交一个一个的重新提交到 master 分支,可能有冲突。解决冲突的办法有二,可以手动解决,也可以自动解决(前面讲 checkout 时有讲)。解决完了 git rebase --continue


我有好几个分支,git 怎么知道我在哪个分支呢?

cat .git/HEAD
 输出:ref: refs/heads/dev2
复制代码

原来是 HEAD 的功劳。HEAD 可以理解成一个引用,它一般情况下是指向分支,有时也指出 commit id。

当你执行 git commit 的时候生成节点 A,A 把 HEAD 认作父节点 ,HEAD 再指向 A。

当你执行 git reset B 的时候  HEAD 指向 B。

当你执行 git checkout C 的时候,HEAD 指向 commit C,这时因为没有分支指向 C,HEAD 这时的状态叫 detatch(分离) 状态。

当你执行 git checkout dev 的时候,HEAD 指向 分支 dev。

美化

毫无章法的提交会让人感觉混乱。如果所有的提交都整齐划一就会让人有正规军的感觉。适当的美化可以让我们用很小的付出得到较大的回报。

提交信息格式化

具体的内容可能参看阮一锋老师的文章 Commit message 和 Change log 编写指南

实操作的时候,注意要结合实际。

提交历史要清晰

在代码 push 之前,最好是先做个检查,对提交做一些调整。可以用之前介绍过的 rebase。一个好的提交历史不仅可以让后面查找的时候方便,也会给别人留下严谨的印象。

参数归类

很多命令都用一样的参数表达同样的意思,看到这样的参数,不用看文档,也能知道它的含意。

  • -q  --quiet 安静。会尽量减少信息输出。
  • -e --edit 打开编辑器。
  • -f --force 强制执行。

到这里并不多就结束了,为了方便大家,最后以附录的形式收集了 git 的一些配置相关的内容。

附录

git 配置

有两个配置每个人都应该设置

git config --global user.name yourname
git config --global user.email youremail    
复制代码

为了让我们的工作更高效,可以对常用命令设置别名。

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
git config --global alias.st status
复制代码

详细完整说明看这里 git配置

这里是一些配置的说明 自定义git

gitignore

gitignore 文件用于指定 Git 应该忽略的未跟踪文件,已跟踪的文件不受影响。 gitignore 文件格式的说明在这里 gitignore 格式

记住几个常用的例子,照猫画虎,可以快速解决问题。

*.a  忽略以 .a 结尾的文件 
!help.a help.a 文件除外,可以被跟踪
/doc 只忽略根目录下的 doc 文件和文件夹
/doc/ 只忽略根目录下的 doc 文件夹
doc/ 只忽略 doc 文件夹
doc 忽略 doc 文件和文件夹
doc/* 忽略 doc 文件夹的内容,不忽略 doc 文件夹本身
a/*/b  * 不能代表 /,不能忽略  a/c/b
a/**b  ** 可以代表任何内容
复制代码

注意,空目录 git 会自动屏蔽。

引用规范

引用规范用来设置 fetch ,和 push的行为的。

具体请看 引用规范

参考

目录
相关文章
|
2天前
|
缓存 数据可视化 网络安全
Git命令大全
Git命令大全
61 1
|
2天前
|
开发工具 git
Git教程:深入了解删除分支的命令
【4月更文挑战第3天】
66 0
Git教程:深入了解删除分支的命令
|
2天前
|
存储 Shell Linux
【Shell 命令集合 文件管理】Linux git命令使用教程
【Shell 命令集合 文件管理】Linux git命令使用教程
37 0
|
2天前
|
开发工具 git
git常用命令整理
git常用命令整理
18 0
|
2天前
|
开发工具 git 开发者
Git常用命令大全:让你轻松驾驭版本控制
Git命令速查:`git init`新建仓库,`git clone`克隆,`git add`入暂存区,`git commit -m`提交,`git status`查看状态,`git log`查看历史,`git branch`创建分支,`git checkout`切换,`git merge`合并,`git pull`拉取更新,`git push`推送,`git remote -v`查看远程,`git checkout --`撤销本地修改,`git reset HEAD`取消暂存,`git reset --hard`回退版本。掌握这些,提升代码管理效率!
23 0
|
2天前
|
Shell 网络安全 开发工具
GIT常用命令
GIT常用命令
|
2天前
|
存储 Linux 开发工具
Git 分布式版本控制系统基本概念和操作命令
Git 分布式版本控制系统基本概念和操作命令
34 0
|
2天前
|
算法 Java BI
云效产品使用报错问题之平台上导出的统计数据和 git 中使用命令导出的数据统计都对不上,如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
2天前
|
存储 开发工具 git
Git大揭秘:掌握开发者必备的常用命令手册
Git大揭秘:掌握开发者必备的常用命令手册
15 0
Git大揭秘:掌握开发者必备的常用命令手册
|
2天前
|
算法 开发工具 git
【git 实用指南】git 增加 本地代码 git add 相关命令和复杂情况需求
【git 实用指南】git 增加 本地代码 git add 相关命令和复杂情况需求
105 0

相关实验场景

更多