Git 经验总结及 Git & GitHub 学习指南

1. 前言

本文主要分为两部分,前一部分是本人学习和工作中使用 Git 的总结经验,后半部分是总结的 Git & GitHub 的学习指南。如果想直接体系学习,可以直接按照指南路线学习。如果你有经验,可以看看第一部分,看看我工作和平时怎么使用 Git 的,看完后如果你有更好的解决方案,或者建议,欢迎评论区交流学习。

2. Git 个人使用总结

2.1 git 简介及工作流程

Git 是一个开源的基于快照流分布式版本控制系统,旨在快速高效地处理从小型项目到大型项目的所有项目。

Git 有三种状态:

已修改:modified,表示修改了文件,但还没保存到数据库中。

已暂存:staged,表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

已提交:committed,表示数据已经安全地保存在本地数据库中。

三种状态分别对应 Git 项目的三个阶段:

工作区:对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。

暂存区:是一个文件,保存了下次将要提交的文件列表信息,一般在 Git 仓库目录中。 按照 Git 的术语叫做“索引”,不过一般说法还是叫“暂存区”。

Git 目录:是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。

基本的 Git 工作流程如下:

  1. 在工作区中修改文件。
  2. 将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。
  3. 提交更新,找到暂存区的文件,将快照永久性存储到 Git 目录。
    Git 经验总结及 Git & GitHub 学习指南_第1张图片

注:图片来源于1.3 起步 - Git 是什么?

更好的理解 Git 的三个区,可以参考文章:Git 工具 - 重置揭密 一文前半部分。

2.2 命令自助查询

首先,要学会自救,忘记命令的用法作用,这很正常,掌握以下命令,我们就不用去刻意记忆 git 命令用法,忘记了,查一下就行。

  • git help :获取命令的作用和使用完整说明,如:git help init

  • git --help:同 git help 。如:git init --help

  • man git-:Linux 下可用,同 git help ,如 man git-init

如果你已经熟悉了 git 命令的作用,只是忘记了它可以使用哪些参数,那么可以使用以下命令,快速查询某个命令能使用的参数及其作用。

git -h:列出指定 git 命令的可用参数,如:git init -h

2.3 git init & git clone

掌握自助查询后,我们就可以开始创建 git 仓库或者拉取 git 仓库。

git init:创建一个空的 git 仓库或者重新初始化一个 git 仓库。一般使用在自己本地新建一个项目,使用 git 进行管理的时候

如:git init ,会在当前目录创建一个 .git 文件夹,这个里面就存储 git 管理当前项目的所有文件。想了解 Git 的原理可以参看Git 内部原理。

git clone:克隆一个仓库到本地当前目录。一般,工作中我们刚进公司,都需要先 clone 一堆仓库到本地,再进行需求开发。或者你发现一个好的开源项目,也可以 clone 到本地,更方便地阅读源码。如:git clone [email protected]:git/git.git

2.4 git add & git commit

我们已经创建好一个 git 仓库,现在我们修改了一些文件,接下来我们需要将修改的文件通过 git 管理起来。

git add:将文件加到暂存区(索引)。比如:git add * 将所有文件添加到暂存区。

git commit:将暂存区修改提交到版本库。如:git commit -m "fix bug001"。如果你本次提交和上次提交的信息一致的话, 可以使用git commit --amend直接将本次修改内容,合并到上一次提交中。避免产生冗余的提交信息。

说明:一般不同公司或者开源项目对于提交格式和信息会有约束,方便他人了解你本次修改的原因。

在 Windows 下开发的话,我推荐 TortoiseGit 工具,TortoiseGit 是Git版本控制系统的免费开源客户端,可以方便的进行 Git 操作。

根据自己习惯和开发环境选择最适合自己的工具即可,目的都是为了提升开发效率。

TortoiseGit 使用文档

2.5 git push

现在我们已经实现了某个功能特性,需要将本地的代码推送到自己的远程仓库,这时我们就需要使用 git push

git push:使用本地的git项目更新远程仓库,也就是将本地修改推送到远程仓库。如:git push --all:将本地所有修改推送到远程仓库。

如果需要强制推送到远程仓库,或者直接使用本地仓库覆盖远程仓库,可以用:git push -f。注意这是一个危险操作,操作前,请确认你正在做什么。

2.6 分支及其操作

分支是 Git 中的一个重要特性,它非常好地解决了开发过程中开发迭代中,软件功能稳定性问题。通常,我们有3种分支。

  • 稳定分支:功能稳定,一般用于构建版本,发布上网。

  • 开发分支:功能相对不稳定,一般用于开发新特性,等新特性稳定后,会阶段性的将新特性回合到稳定分支。

  • bug修复分支:解决稳定分支发现的bug,需要同时合入稳定分支和开发分支。

分支管理是一门艺术,分支越多,维护成本会越高,这里就不展开了。

下面主要介绍下分支的基本操作:查看、创建、切换、删除。

2.6.1 查看分支

git branch:查看分支。

[root@TanjyAliyun demo]# git branch 
  dev
* master

* 标识当前 HEAD 指针指向的分支,也就是当前所在的本地分支。在 Git 中,HEAD是一个指针,指向当前所在的本地分支,可以将 HEAD 想象为当前分支的别名。

2.6.2 创建分支

git branch :基于 HEAD 创建 新分支,但不会自动切换到新分支。如:git branch dev:创建 dev 分支。

git checkout -b :基于 HEAD 创建并切换到新分支。如:git checkout -b dev:创建 dev 分支,并切换到 dev 分支。

git checkout -b -m commit-id:基于当前分支的某一次 commit-id 创建并切换到 新分支。

一般使用场景:

  1. 临时备份本地修改。比如:有一个新特性, 在dev分支还没完全开发完,无法上库,这时 dev 分支有个紧急bug需要修复,这时可以新建一个 tmp 分支备份修改,再将 dev 分支上的特性开发 reset 掉,然后进行 bug 修复,等bug修复提交合并后,再从 tmp 临时分支 pick 特性开发到 dev 分支,然后删除 tmp 分支,就可以继续在 dev 分支进行特性开发了。
  2. 紧急 bug 修复。有一个新特性, 在dev分支还没完全开发完,无法上库,这时 dev 分支有个紧急bug需要修复,这时可以基于特性开发前的 commit-id 新建一个分支 bug-fix,进行修复bug,等bug修复提交合并后,再切换回dev分支,删除 bug-fix 分支,继续开发特性。具体过程如下:
[root@TanjyAliyun demo]# git branch 
* dev
  master
[root@TanjyAliyun demo]# git log
commit 2ac24ccead054b679a56613dfb72a4b40102e6ce
Author: jock <6666@hw.com>
Date:   Wed Aug 3 21:53:33 2022 +0800

    add b.txt

commit e48eb6abdb2e0bc525036f3e528b674d32809e3c
Author: jock <6666@hw.com>
Date:   Wed Aug 3 21:51:51 2022 +0800

    add a.txt

commit f1d00a5251278236f322f0a58c712c59cb3a4cda
Author: jock <6666@hw.com>
Date:   Wed Jul 13 21:41:12 2022 +0800

    add test.txt
[root@TanjyAliyun demo]# git checkout -b bug-fix-0804 -m f1d00a52512
Switched to a new branch 'bug-fix-0804'
[root@TanjyAliyun demo]# git branch 
* bug-fix-0804
  dev
  master
[root@TanjyAliyun demo]# git log
commit f1d00a5251278236f322f0a58c712c59cb3a4cda
Author: jock <6666@hw.com>
Date:   Wed Jul 13 21:41:12 2022 +0800

    add test.txt
[root@TanjyAliyun demo]# git branch 
* bug-fix-0804
  dev
  master
[root@TanjyAliyun demo]# git checkout dev 
Switched to branch 'dev'
[root@TanjyAliyun demo]# git branch -d bug-fix-0804 
Deleted branch bug-fix-0804 (was f1d00a5).
[root@TanjyAliyun demo]# git branch 
* dev
  master

2.6.3 切换分支

git checkout xxx:切换到 xxx 分支。

2.6.4 删除分支

git branch -d xxx:删除 xxx 分支。

2.7 git fetch vs git merge vs git full

接下来,我们可能先clone了项目,但是本地一直没有做修改,同事合入了很多代码到项目中,这时我们想知道同事改了啥。就可以用到以下命令:

git fetch:从服务器拉取本地没有的数据,但它不会修改本地工作目录中的内容,它只抓取服务器数据,需要你自己合并。

git merge:将另一个分支的修改合并到当前分支。如:当前 HEADE 是 master 分支,使用 git merge dev 命令表示,将 dev 分支合并到 master 分支。

git pull:等于 git fetch + git merge,拉取并合并远程分支到当前分支。

2.8 fast-forward vs no-fast-forward vs fast-forward-only

接下来,介绍一下,git merge 合并的三种处理方式:

  • fast-forward:快进式合并,不会生成额外的合并 commit 记录。快进行合并的前提是本地当前分支没有修改,远程分支有合入。Git 很懒,默认先采用快进式合并,如果没法进行快进式合并, Git 就会使用非快进式方式合并。如:git merge --ff dev
  • no-fast-forward:非快进式合并,无论能否进行快进式合并,Git 都会生产额外的合并commit记录。如:git merge --no-ff dev。通常我们本地开发有提交记录,远程仓库有同事合入,这时拉取合并远程分支时,就会使用非快进式合并,生成合并 commit 记录。
  • fast-forward-only:只进行快进式合并,无法进行快进式合并时,放弃合并。如:git merge --ff-only dev

本地和远程都有提交记录时,还想使用fast-forward-only 模式合并,那么就需要用到 变基(git rebase)命令了。

2.9 git rebase

git rebase:变基。改变当前分支修改的老基准,将其他分支的最新提交作为新基准,当前分支修改移动到其他分支最新提交之后。

比如:

当前分支(master):基于 commit A 做了修改,提交了 commit B。

其他分支(dev):基于 commit A 做了修改,提交了 commit C。

此时,想要将 dev 分支的修改通过快进式合并到 master 分支,可以如下操作:

  1. 切换到,dev 分支,使用 git rebase master命令,将dev分支的修改基准由commit A 变更到 master 的最新提交 commit C。
  2. 再切换回 master 分支,使用 git merge --ff-only dev,只进行快进式合并 dev 分支到 master 分支。

使用git rebase需要遵守一个准则:**如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。**

git rebase 可以让我们的提交历史更加干净,但也会破坏提交历史。使用 git merge 还是 git rebase 好?其实是两种观点的体现。

这里不过多展开了。基于当前我工作公司的Git管理现状,采用 rebase 更加合适。所以git pulll -r --ff-only是我常用的命令之一。

更多的关于 rebase 的比对,大家可以参考这篇文章:Git 分支 - 变基。

2.10 git cherry-pick

有时,我们不想直接合并某个分支,只需要某个分支上的某次修改,这时我们就可以使用 git cherry-pick 来很好完整这个工作。

git cherry-pick:将指定的修改合并到当前分支。

我工作中,经常遇到一个bug 的修复需要合入多个分支,这时我会在一个分支修改,其他分支采用 cherry-pick 的方式完成。

git cherry pick也很强大,可以通过 git cherry-pick --help 命令查看更多官方命令说明。

2.11 git reset vs git revert

如果我们想回退到指定阶段的版本,那么我们可以使用 git reset命令

git reset:重置当前指针(HEAD)到指定状态。可以帮助我们快速的回到历史某个版本。

git reset 支持三种模式:

  • git reset --soft:只移动 HEAD 指针,只影响 Git 目录,索引区和工作区不受影响。
  • git reset --mixed:移动 HEAD 指针,同时用 Git 目录更新索引区内容。Git 默认行为。
  • git reset --hard:移动指针,同时用 Git 目录更新索引区和工作目录。危险操作,会真正的销毁数据

工作中,我经常使用 git reset --mixed或者git reset --soft来修改提交记录。开发过程中,小步快跑,多次提交,但是正式上库(推送到远程仓库)时,需要把之前的小步提交合并成一个提交,以保证git 记录更加简洁,这时就可以先 reset ,然后把所有修改文件重新提交为一次 commit。

工作中,有时发现开发的一个特性,方案有问题,或者实现不合理,本地修改完全不可用,且没有上库,这时我就会用 git reset --hard删除本地所有修改。

更多有关 git reset 的信息,可以参考Git 工具 - 重置揭密。

工作中有时会遇到这种场景:我们刚刚合入到远程仓库的修改有问题,导致了一个 bug,需要紧急回退修改,保证原来功能正常。这时git revert就派上用场了。

git revert:回退指定 commit 修改,同时会生产一个回退 commit 记录。

2.12 git stash

有时工作目录有文件没有提交到版本库,这时也可以使用 git stash 来暂存工作目录的修改。等拉取远程分之后,再使用git stash pom来恢复暂存的修改。

git stash:暂存工作目录未提交的修改。

2.13 多个连续 commit 合并为一个 commit

开发小步快跑时,正式上库前想将多个 commit 记录合并为一个 commit 记录,除了使用 git reset外,还有一个办法是使用 git rebase -i。如:git rebase -i HEAD~3将最近的三次提交合并为一次 commit。

工作中,因为是使用 Windows 开发,所以基本我使用 TortoiseGit 工具 来完成这个 Git 操作。

更多的用法请使用 git rebase --help查看。

2.14 关联其他仓库

本地 Git 项目可以关联 N 个远程或者本地其他 Git 项目,关联后,我们就可以将远程或者本地的其他 Git 项目修改 pick 或者 merge 到本地当前 Git 项目,也可以将本地 Git 项目修改推送或者 pick 到关联的 Git 项目。

工作中,通常我会将本地 Git 项目关联两个远程仓库,top 库(大家都合入,用于构建版本上网的仓库),origin(个人二级仓库,用于申请合并到顶级仓库)。添加远程仓库可以用以下命令:

git remote add:如git remote add top [email protected]:TortoiseGit/TortoiseGit.gitgit remote add origin [email protected]:Jock2018/TortoiseGit.git

前段时间,我需要关联一个本地的仓库做 merge 操作,可以使用类似如下命令:

git remote add local_remote /opt/mycode/TortoiseGit/.git

更多操作参考:git remote --help

2.15 取消关联仓库

如取消关联 local_remote:

git remote remove local_remote

2.16 解决冲突

工作中难免避免会有冲突,比如代码回合或者代码拉取时,这时就需要处理冲突。

冲突的处理需要经验积累,经过两年的工作,和几次代码回合的处理经验,我如今也能熟练的应对冲突。有以下心得:

  1. 代码回合时,根据修改多少、冲突情况、项目管理实际,灵活使用 pick 或者 merge 进行回合。如果可以预见冲突少,直接merge是一个好的选择。如果合入 commit 少,直接 pick 也是一个好的选择。
  2. 遇到冲突,不确定选择本地的还是远程的作为最终版本,一定要找当时修改这部分代码的人确认。
  3. 一个好的顺手的工具,可以有效提升处理冲突的速度。如果是使用 Windows 开发,我依然推荐 TortoiseGit 工具 来完成冲突处理。

2.17 git 常用配置

git 配置分三个层级,本地–> 全局 --> 系统 ,三个层次中每层的配置都会覆盖上一层次的配置,遵循就近原则,所以 .git/config中的值会覆盖/etc/gitconfig中所对应的值。

这里我还是以工作中 Windows 下开发为例,介绍一些常用的配置:

  1. 配置用户名和邮件地址:

git config --global user.name "Jock"

git config --global user.email [email protected]

  1. core.autocrlf

    • git config --global core.autocrlf true:假如你正在 Windows 上写程序,而你的同伴用的是其他系统(或相反),Git 可以在你提交时自动地把回车和换行转换成换行,而在检出代码时把换行转换成回车和换行。可以用 core.autocrlf 来打开此项功能。 如果是在 Windows 系统上,把它设置成 true,这样在检出代码时,换行会被转换成回车和换行。
    • git config --global core.autocrlf inputcore.autocrlf 设置成 input 来告诉 Git 在提交时把回车和换行转换成换行,检出时不转换。适用于产品运行在 Linux,但是开发在本地的场景。在我工作的公司,这个设置是必须的,否则会导致本地构建的版本无法成功安装部署。
    • git config --global core.autocrlf false:如果你是 Windows 程序员,且正在开发仅运行在 Windows 上的项目,可以设置 false 取消此功能,把回车保留在版本库中。一般这种场景比较少,现在程序很多都跑在 Linux 的生产环境中。
  2. pull 设置

    git config --global pull.rebase true:采用 rebase 方式合并远程方式,而不是采用 merge 方式。这样可以避免顶级库合并到本地的 commit 记录。

    git config --global pull.ff only:只采用快进式拉取合并远程库,否则不拉取。需要配合 git rebase使用。

  3. commit 设置:

    git config --global commit.template C:\Users\tanjy\commit-message.txt:指定提交信息模板。我一般使用 TortoiseGit 工具,它能方便记住历史提交信息,已经非常方便了。

    以上配置完成后,全局 git 配置文件内容大致如下:

    [user]
    	name = Jock
    	email = [email protected]
    	signingkey = ""
    [core]
    	quotepath = false
    	autocrlf = input
    [fetch]
    	prune = false
    [pull]
    	rebase = true
    	ff = only
    [commit]
    	template = C:\\Users\\jock\\commit-message.txt
    

    更多的配置说明请参考官方文档,组合出适合你当前公司,最高效的配置就行。

    1. 自定义 Git - 配置 Git

    2. git 配置官方说明

2.18 ignore 文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表, gitignore GitHub 地址。

工作中,一般一个代码仓库,在根目录配置一个 .gitignore即可。

更多的请参考:忽略文件

以上就是个人作为后端研发经常使用的一些 Git 操作和配置,可以发现,这里主要都是针对客户端的,至于服务端的配置和使用,大家可以参考下面的学习指南进行系统学习。Git 还有很多高级操作,比如钩子的配置等,建议大家有时间,可以快速过一下Git Pro这本书,了解 Git 都能干哪些事,方便需要时,快速查找。

3 Git & GitHub 学习指南

3.1 Git 基础

  • 目标

    1. 了解 Git 基本概念和常用命令作用(理论)
    2. 能够使用 Git 命令来管理和提交项目代码(实战)
  • 基本概念

    • 什么是 Git (版本控制系统)
    • 什么是 GitHub (代码托管平台)
    • Git 和 GitHub 的作用
    • Git 和 GitHub 的联系和区别
  • Git 基本概念

    • 工作区
    • 暂存区(索引)
    • 本地版本库
    • 远程仓库
    • Git 文件状态
    • 版本
    • HEAD
    • 分支
  • Git 安装

  • Git 常见配置

    • 修改配置

      • 个人信息
    • 查看配置

  • Git 基本操作(开发流程)

    • 初始化仓库(git init)
    • 克隆(git clone)
    • 暂存(git add)
    • 提交(git commit)
    • 推送(git push)
    • 拉取(git fetch)
    • 拉取合并(git pull)
    • 查看状态(git status)
    • 查看历史(git log)
  • 分支操作

    • 创建分支
    • 查看分支
    • 切换分支
    • 删除分支
    • 合并分支(git merge)
  • 推荐资料

    • 猴子都能懂的 Git 入门
    • Learning Git Branching 游戏理解分支
    • 工具详解 - Git 详解
    • 99%的时间在使用的Git命令
    • GIT分支开发模型规范
    • Git - 简明指南
    • 图解 Git
    • 廖雪峰 : Git 教程

3.2 GitHub 基础

  • 目标

    1. 熟悉 GitHub 基本操作,并能够使用 GitHub 来管理代码
    2. 了解如何利用 GitHub 搜索和下载项目代码
    3. 了解 GitHub 协作流程,了解开源,并能向开源项目提交代码
  • 知识点

    • 什么是 GitHub

    • 如何访问 GitHub

    • 基本概念

      • 仓库

      • 分支

        • 主分支
      • READEME

      • STAR

      • Follow

      • 账号类型(个人/组织)

    • 必备操作

      • 搜索仓库/代码

      • 创建仓库

        • 公开
        • 私有
      • Fork 仓库

      • Watch 仓库

      • 上传本地代码

      • 修改个人信息

    • GitHub Flow 协作流程

      • 克隆/Fork仓库
      • 创建分支
      • 修改代码
      • 发起 Pull Request
      • CodeReview
      • Merge 分支
      • 删除分支
    • 了解 GitHub issues

    • 共享代码流程

  • 推荐资料

    • GitHub 入门教程
    • GitHub 漫游指南
    • 开源指北

3.3 Git 进阶

  • 目标

    1. 学习 Git 高级操作,尤其是能够熟练地规避和解决冲突
    2. 了解企业常用的 Git 协作流程和规范,能独立管理项目
  • 知识点

    • 高级操作

      • 标签(git tag)
      • 检出(check out)
      • 贮藏(git stash)
      • 清理(git clean)
      • 变基(git rebase)
      • 重置(git reset)
      • 还原(git revert)
      • 检索(git grep)
      • 展示差异(git diff)
      • 溯源(git blame)
      • 参考日志(git reflog)
      • 交互式命令行(-i 参数)
    • 预防冲突

    • 解决冲突

    • 配置 SSH

    • 子模块

    • Git 钩子

      • 提交钩子(pre-commit)
    • 忽略提交(git ignore)

    • cherry-pick

    • 分布式工作流程

    • Git worktree

    • Git Flow

    • Git 内部原理

    • Monorepo

    • 了解其他版本控制系统,和 Git 对比

  • 推荐资料

    • Git Pro

3.4 GitHub 进阶

  • 目标

    1. 按需学习更多 GitHub 功能,提升研发效率、更好地管理项目
    2. 尝试用心维护和推广自己的 GitHub 项目
  • 开发

    • 配置 SSH 拉取
    • GitHub 快捷键
    • GitHub 命令面板
    • GitHub Apps
    • 代码安全
  • 协作

    • GitHub Codespaces
    • GitHub Discussions
    • Pull Requests
  • 项目管理

    • Organizations 组织
    • GitHub Issues 问题反馈
    • Insight 数据分析
    • 贡献者管理
    • 开源协议
  • 推荐资料

    • GitHub 官方文档

以上Git & GitHub 学习指南参照 程序员鱼皮的总结。

4. 参考资料

所有参考资料均在文中给出了相应链接。

你可能感兴趣的:(开发部署工具,git,github)