前言

曾经稍微学习过一点git,对git稍微有一点认识,但也仅仅是知道他是干嘛的。本笔记主要用来记录一下git的常用命令和功能以及我的一些个人理解。


什么是git

对于什么是git,官方文档是这样介绍它的:
Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.

总结下来,git是一个可扩展的分布式的 版本控制系统


安装git

通过官方下载网站下载相应安装包正常安装,当鼠标右键出现Git Bash Here时即为安装成功

对于Debian/Ubuntu等一些常见的Linux发行版,可以直接通过默认的包管理工具进行安装,参照官方Linux安装指南


也可以通过源码进行安装,源码安装方式如下:

在该镜像网站下载对应版本的git源码,然后./configure prefix=/usr/local/git/,然后make && make install,最后将git指令添加到环境变量即可

安装完git之后,必须配置用户名和邮件,配置方式如下(二选一即可):

  • 使用命令行
1
2
git config --global user.name "Your Name"
git config --global user.email "Your Email"
  • 编辑 ~/.gitconfig 或者 /etc/gitconfig 文件
1
2
3
[user]
name = Your Name
email = Your Email

创建git仓库

进入到要创建仓库的目录下

  • 输入git init即可创建一个空仓库
  • 输入git add [文件名]即可把文件写入暂存区(文件名支持通配符,如*.cpp)
  • 输入git commit -m [提交原因]即可把暂存区 修改写入当前分支

注:可以add多次后进行commit,一次commit即可把暂存区全部修改提交到当前分支版本库


版本控制

状态查看

git status命令可以查看工作区的状态,也可以查看哪些文件被修改了

git diff命令可以查看文件修改的具体内容,但是无法查看二进制文件如word文档,图片等的修改内容

版本回退

git log命令可以查看提交历史commit id(版本号)、作者、邮箱、日期以及commit的原因,如果只想查看版本号以及commit原因,可以加上一个参数,使用如下命令git log --pretty=online,常用于撤销 操作

git reflog命令可以查看命令历史的commit id等相关信息,常用于撤销后的重做 操作

git reset --hard commit-id命令可以使文件在不同版本之间跳转,需要注意的是,在git中 HEAD 表示当前版本,那么 HEAD^ 就表示上一个版本,HEAD^^ 就表示上上一个版本,如git reset --hard HEAD^就表示回到上一个版本

撤销修改

git checkout -- [文件名]命令可以丢弃工作区的修改,使用此命令会产生两种情况

  • 该文件自修改后还未放到暂存区,那么执行此命令后该文件就回到了当前版本库(最后一次commit)的状态
  • 该文件已经添加到了暂存区,那么执行此命令后文件就回到了暂存区(最后一次add)的状态

小提示:此命令也可用于在工作区误删文件后的文件恢复

git restore --worktree [文件名]命令可以将文件回到暂存区状态

git reset HEAD [文件名]命令清除所有暂存区的内容,对工作区没有影响

删除文件

git rm [文件名]命令可以将文件从版本库中删除


分支管理

一个分支下的修改不会影响到其他分支,所以往往使用一个dev分支做具体项目开发,该分支下又有多个子分支来实现不同的功能和细节,每当有一个具体的新版本发布,就将dev分支合并到master分支。master分支往往不会进行具体的操作,只是负责发布稳定版本

git branch命令可以查看当前分支

git checkout -b [分支名]创建并切换到新分支 = git branch [分支名]创建新分支 + git checkout [分支名]切换到一个已有分支

注意:此命令与上述撤销修改命令有些相似,可以会难以区分,推荐使用下述命令

git switch -c [分支名]创建并切换到新分支

git switch [分支名]切换到一个已有分支

git merge [分支名]把指定分支名的修改合并到当前分支,默认以Fast-forword模式合并

git branch -d [分支名]删除分支

git merge --no-ff -m [提交原因] [分支名]以普通模式将dev合并到当前分支,并进行一次提交


标签管理

标签其实就是给某次commit打上一个记号,常用于版本发布时的版本号。有点类似于给commit id起个名字

git tag查看所有标签

git tag [标签名] ([commit id])给指定commit打上一个标签,默认是HEAD

git tag -a [标签名] -m [描述信息] ([commit id])打上一个标签,并添加描述信息

git show [标签名]查看标签信息

git tag -d [标签名]可以删除一个标签


远程仓库

远程仓库就是一个搭建在服务器上的git仓库。通过git工具,我们可以很方便的将远程仓库的内容拉取到本地,也可以将本地的内容推送到远程仓库

ssh-keygen -t rsa -C [邮箱地址]输入命令后一直回车即可。此命令可以生成一个rsa公钥,默认存放在 C:/user/用户名/.ssh 目录下,id_rsa是密钥,id_rsa.pub是公钥。将公钥放到远程仓库的 SSH Keys 中即可实现对远程私有仓库的读写,类似于一个身份证

git clone [仓库地址]将远程仓库克隆到本地,仓库地址有以git开头的ssh协议和以http/https开头的http/https协议以及一些其他的如github-cli协议

git remote add [仓库名称] [仓库地址]仓库名称通常命名为origin,这是默认的叫法

git push -u origin master把本地的master分支推送到远程的origin仓库,只需要在第一次加上 -u 参数

git push origin [标签名]将一个本地标签推送到远程服务器

git push origin --tags将所有标签推送到远程服务器

git push origin :refs/tags/[标签名]删除一个远程标签

git fetch [仓库地址] ([分支名])将远程仓库的指定分支取回到本地,不填分支名则默认是所有分支

git pull从远程仓库获取最新版本并合并到本地 = git fetch + git merge


git子模块的使用

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个

git 子模块就是在一个 git 仓库中嵌套另一个/多个 git 仓库,有点像套娃。我们可以对每一个子模块单独进行管理

添加子模块

git submodule add [仓库地址] [存放路径] 在父项目中添加一个子模块

git submodule 查看所有子模块

git submodule update --remote [子模块名] 更新指定子模块

git submodule update --remote 更新所有子模块

git push origin HEAD:master 子模块向远程仓库提交修改

克隆一个含有子模块的项目

方法一:先克隆父项目,然后克隆子项目

  1. git clone [父项目地址] 克隆父项目

  2. git submodule init 初始化本地子模块配置文件

  3. git submodule update 从该项目中抓取所有数据并检出父项目中列出的合适的提交

方法一简化:命令合二为一

  • git submodule update --init = git submodule init + git submodule update

  • 如果还要初始化、抓取并检出任何嵌套的子模块,可以使用 git submodule update --init --recursive

方法二:递归克隆父项目和子项目

git clone --recurse-submodules [父项目地址] 自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块

删除子模块

  1. 删除子模块文件夹

rm -rf [子模块名]

  1. 删除 .gitmodules 文件中的子模块信息
  2. 删除 .git/config 文件中的子模块信息
  3. 删除 .git/module/ 目录下的子模块的目录

rm .git/module/[子模块名]

  1. 清除子模块缓存

git rm --cached [子模块名]


参考资料

【1】:Git-Reference

【2】:廖雪峰的官方网站

【3】:阮一峰的网络日志