1. git常用命令详解
相信每一个开发者都使用过或者说是听过git,比如大名鼎鼎的"全球最大同性交友网站--GitHub"就是利用git这一分布式版本控制系统来管理大家的项目的;
一般公司内的代码管理常见有两种,一个是SVN,一个是GIT;当然后者更常见,作为一个码农,如果不想被身边的小伙伴鄙视or吐槽,掌握基本的git操作技巧属于必备的生存技能了,本文不会带你成为git专家,更多的是介绍作为一个开发者,在日常的工作中,经常使用git命令以及必备的git技巧
本文主要包含以下知识点
- 环境安装,配置
- 获取代吗,提交本地修改并推送
- 分支创建、切换、删除,合并
- 标签的使用姿势
- 如何回滚,暂存
- 代码冲突怎么办
- 手误提交了敏感信息,如何彻底删除
I. 基本篇
为方便国内的小伙伴正常使用,我们以Gitee作为演示的git服务器,关于git的基本使用姿势与github并无差别
0. Git安装
首先我们得安装git环境,下面简单介绍一下Win/Linux/Mac三个操作系统下的安装姿势
a. win
在官网https://git-scm.com/download/win下载安装包,完成windows平台的安装
完毕之后,找到git bash
或者是git terminal
,打开一个类似终端的窗口,输入git --version
命令,如果正常返回,则表示ok
b. linux
linux环境下,通常可以借助apt-get
or yum
来安装,如
## ubuntu
sudo apt-get install git
## yum
sudo yum install git
对于其他的linux/unix操作系统,具体的安装命令可以查看: Download for Linux and Unix
c. mac
Mac自带git,因此完全是可以开箱即用;当然如果我希望体验最新的git,推荐通过homebrew
来安装
sudo brew install git
1. 基本配置
git安装完毕之后,需要配置我们的ssh密钥,通过密钥来实现与git服务器之间的校验(避免每次都输入用户名/密码,而且安全性更高)
a. 判断是否存在
首先到根目录确定是否已经有了密钥
# 查看文件夹下的资源
# 如果目录 .ssh 不存在,or目录下为空,则表示我们需要生成密钥
$ ls ~/.ssh
b. 生成密钥
生成密钥: 输入ssh-keygen,并一直回车
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/deploy/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/deploy/.ssh/id_rsa.
Your public key has been saved in /home/deploy/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:IxeVFUFw1y/ZIE0xwh9E8UJMlxwsYwwOp5m2yy7FANI deploy@localhost
The key's randomart image is:
+---[RSA 2048]----+
| . .oOXX&=+|
| . E .O.oO=B.|
| . . .= ..o+=o|
| .... +.o|
| . S. . |
| o.+. |
| .o |
| .. |
| .. |
+----[SHA256]-----+
接下来在~/.ssh
目录下将可以看到id_rsa
与id_rsa.pub
两个文件,接着我们需要将id_rsa.pub
的内容,复制到gitee上,用于后续的git交互鉴权
c. 配置公钥
查看公钥内容
$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIK4Skx1ZKYBlKbO5dhCpTbknUEXhiSiOtB+PSnbaQx+ZwVK+Lz3EVs3qj9qotos7kmj6CbcZDbbSVKbCM6ChYBR9k81TgB4q1CxpP7mCAe4Z2m2gAHv+POnsyXzWtvWm4E3FXliJz9/1fWRCcS+iBIyjmZcab8nvt8RqPiPL1zmW72EcyRhckNvFItiHp3aukWhF/4DUOwvjY/ms9QM7nKkZaA2uXc+Z9K4QJCRZ1vIGEqqgKQnsXtpRQXNPaaldaELo4tyzOJLv6JWJ64qEMqtrRWjpXSZOFO2QCts/bWCITwfkllLTlj+i+rV9yysPrSUbuXlTf4ZMBOWWvp/nB yihuihuiyi@gmail.com
进入gitee的ssh公钥添加页面: Gitee SSH公钥配置
d. 测试
上面的密钥作为测试密钥,写完本篇文章的时候已经删除掉了,建议大家使用自己的账号进行测试
然后开始测试我们的配置是否ok,借助ssh -T git@gitee.com
, 使用github的小伙伴,这个命令改成 ssh -T git@github.com
$ ssh -T git@gitee.com
The authenticity of host 'gitee.com (212.64.62.174)' can't be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.
ECDSA key fingerprint is MD5:27:e5:d3:f7:2a:9e:eb:6c:93:cd:1f:c1:47:a3:54:b1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitee.com,212.64.62.174' (ECDSA) to the list of known hosts.
Hi 一灰灰Blog! You've successfully authenticated, but GITEE.COM does not provide shell access.
2. 创建or同步项目
在开始之前,推荐全局配置用户名和邮箱
git config --global user.name "一灰灰Blog" git config --global user.email "bangzewu@126.com"
接下来我们开始进入正文(是的,前面都是开胃菜,完全可以跳过),一般来说,我们会有下面三种case,分别说明
a. 从0到1创建新项目
在gitee上创建一个空的仓库,步骤如下图的1,2,3,4
接下来在你自己的机器上,开始创建项目
mkdir git-study
cd git-study
git init
touch README.md
git add README.md
git commit -m 'first commit'
git remote add origin https://gitee.com/liuyueyi/git-study.git
git push -u origin master
b. clone已有项目
clone一个已有的项目可能更加常见(毕竟实际的工作中,享受创建项目的人比较是少数)
git clone https://gitee.com/liuyueyi/git-study.git
cd git-study
echo 'hello git' 1> README.md
git add .
git commit -m 'first modify'
git push -u origin master
c. 已有项目关联
我本地有一个项目,gitee上有一个非空的仓库,我希望将这两个项目关联起来,可以如下操作(这个过程和第一个其实差不多)
# 在上面的项目基础上进行操作
rm -rf .git
git init
git remote add origin https://gitee.com/liuyueyi/git-study.git
# 本地创建master分支(关于分支的创建后面有介绍)
git checkout master
# 同步最新的代码
git pull
echo 'second modify' 1> README.md
git add README.md
git commit -m 'second modify'
git push
d. 小结
创建git项目的三种方式
- 从0到1创建:
# 初始化git git init # 与远程关联 git remote add origin https://gitee.com/liuyueyi/git-study.git # 本地做一些修改 ... # 提交 git push -u origin master
- clone:
git clone https://gitee.com/liuyueyi/git-study.git # 本地做一些修改 ... # 提交 git push
- 已有项目:
git init git remote add origin https://gitee.com/liuyueyi/git-study.git # 同步最新代码 git checkout master git pull # 本地做一些修改 ... # 提交 git push
3. 修改提交
接下来进入我们日常工作中,接触频率最高的几个操作,提交本地修改并推送到服务器
a. 基本操作
首先我们新增一个文件,并修改README.md
echo 'add new file' 1> new.txt
echo 'some new code' 1> README.md
在我们提交之前,先查看一下当前的状态,可以知道我们有哪些修改,有哪些需要提交
git status
上面只是给出了修改or新增or删除的文件,但是并不知道修改了什么,这个时候可以借助diff
来查看
git diff
接下来确认没有问题,希望将修改的内容提交给服务器
# 将README.md的修改,添加到暂存区
git add README.md
# 如果是希望将所有的改动都添加到暂存区,可以如下使用
git add .
使用git commit
指明这次提交的说明
git commit -m '修改并提交'
推送改动
# 精确指定推送到哪个分支
git push -u origin master
# 当本地分支与远程分支建立过绑定关系之后(如上面的操作),则可以省略后面的参数,直接如下操作即可
git push
b. 小结
这一小节的内容虽然简单,但是在实际的工作中,基本上100%会出现,所以这一小结的所有内容都属于必须熟练掌握的知识点
- 查看本地改动:
git status
- 将本地修改提交到暂存区:
git add
- 提交commit信息:
git commit -m '这次提交的详细说明'
- 推送暂存区内容:
git push
orgit push -u origin master
4. 回退
在git的使用过程中,不太可能总是一帆风顺,有些时候发现提交了错误的请求到暂存区了,也有可能我需要回滚到之前的某个版本,那么可以怎么处理呢?
a. 工作区与暂存区
这一小节属于扩展,不了解这两个概念不影响你的日常操作,但是了解之后可能更有助于理解add/commit
的作用
工作区
可以简单的理解为我们的项目目录,比如在我们的项目中添加、修改or删除文件,这些都是工作区的操作
暂存区
通过git add
可以将工作区的变动,提交到暂存区
注意:如果此时再次修改已经提交到暂存区的文件,那么新的变动依然是在工作区,只有再次git add
之后,变动才会同步到暂存区
本地分支
通过git commit
将暂存区的变动,提交到当前分支
注意:提交到分支之后,工作区就变得干净了,但是本地的分支会领先服务器,通常这时候建议将本地变动通过git push
同步到服务器
b. 版本回退
在我们的git操作历史中,可能有很多次提交,可以通过git log
来查看历史日志
git log
在历史的提交版本中,当我希望回到某个版本时,借助git reset --hard/soft 版本号
来实现
git reset --hard 72920bfd579ada7e62ceed2c675bce733e804433
请注意,上面的 --hard
回滚到指定的版本,且会丢弃这个版本之后的修改,也就是说我们的项目,完全回到了这个版本的时候的状态
回到之前的版本容易,但是如果这个时候我又想恢复回去,该怎么搞呢???
- 借助
git reflog
查看历史操作记录(当然也可以直接在git服务器的commit历史上去查) - 第二种姿势就是直接
git pull
拉一下最新的代码... (这种只适用于所有的本地暂存都提交给服务器的情况,当你本地有一个暂存只是commit,但是没有push,那么无法同步到哦,这种case请使用下面的姿势)
# 查询每次操作命令
git reflog
# 找到reset之前的commit id,回滚即可
git reset --hard 3d85a2f
请注意上面的--hard
参数,回滚到指定的版本,而且会丢掉之后的改动,那么如果我希望保存修改呢?
git reset --soft 72920bfd579ada7e62ceed2c675bce733e804433
鉴于回退到上一个版本属于非常基础和常见的场景,我们可以使用HEAD^
来表示回退到上一个版本,HEAD^2
表示回退两个版本,这样就不需要每次去找Commit号了
# 回退到上一个版本
git reset --soft HEAD^
# 回退两个版本
git reset --soft HEAD~2
c. 撤销修改
在我们日常开发过程中,可能会遇到某个文件(or多个文件)上的修改不是我想要的,希望把这些修改都丢弃,这个时候可以怎么办呢?
借助git checkout
来实现我们的目的,基本操作姿势如下
git checkout -- README.md
在上图中,详细的演示了修改文件,并丢弃修改的全过程,请注意checkout后面的--
,用来指定文件;在后面介绍分支的时候,也会看到这个命令,可以用来切换分支;当后面没有--
时,若后面跟上的参数对应分支存在,则切换分支;否则表示丢弃后者工作区中的改动
上面针对的是没有提交到暂存区的撤销,那么针对暂存区的撤销呢?
# 取消暂存
git reset HEAD README.md
# 撤销修改
git checkout -- README.md
既然上面提到了add之后的撤销,那么commit之后的撤销呢?我们上面介绍的版本回退其实就可以实现这个效果
git reset --hard HEAD^
d. commit修改
有些时候,commit对应的注释信息可能不太合适,然后我希望可以修改一下,可以如下操作
git commit --amend
此外,当我们将改动commit到本地分支之后,忽然发现还漏了一个改动,这个时候也可以借助上面的commit --amend
来合并提交哦
e. 小结
本节内容主要介绍了版本回退和撤销本地修改的一些操作,主要需要掌握以下几个命令
- 工作区/暂存区/分支:
add
将工作区修改提交到暂存区,commit
将暂存区修改提交到分支,push
将本地分支同步到服务器 git log
:查看历史的git提交记录git reflog
: 本地操作记录git reset --soft/hard commitId
: 回退到指定commitId的版本,--soft
表示保留修改,--hard
表示丢弃修改git checkout -- file
: 丢弃指定文件的改动git commit --amend
: 提交信息修改和合并
5. 分支
我们上面的所有操作都是在默认的master分支上进行的,但是在实际的业务开发中,基本上没有哪个公司的项目只有一个分支的,试想一下所有的小伙伴都在同一个分支上开发新的功能模块,结果现在出了问题,我们要修复线上bug,但是新开发的功能又不能上线,这个时候就是灾难性的结果了
a. 分支创建
除了在Gitee/GitHub页面创建新分支之外,本地有两种常见的分支创建方式
# 创建分支
git branch dev
# 创建并切换到res分支
git checkout -b res
b. 分支切换
在上面的示意图中已经演示了如何切换分支
# 切换到dev分支
git checkout dev
请注意这里用的也是checkout,与前面丢弃工作区修改命令一致,区别在于后面接上的分支存不存在,存在切换分支;不存在则丢弃修改(丢弃工作区修改,也可以加--
来限定)
c. 删除分支
一般建议删除本地分支之前,请确保分支的内容已经合并到主分支,否则可能造成数据丢失哦
# 删除dev分支
git branch -d dev
# 当我们对dev分支有修改,但是没有提交的时候,删除时会提示是否强删
git branch -D dev
d. 分支查询
# 查看本地分支
git branch
# 查看本地+远程分支
git branch -a
e. 分支提交
当我们在新的分支上进行开发,并有需要提交时,直接使用git push
多半是不会成功的,这个时候需要指定提交到的远程分支,并建立关系
# 推送远程res分支
git push -u origin res
疑问:本地res分支,能推送到远程的master
分支么
请注意上面的提示,并不是推送成功哦
f. 分支合并
创建新的分支,并在新的分支上进行开发,最终必然会有一个将分支内容合并到主分支的过程,分支合并常常会带来另外一个问题,冲突解决,这个会在进阶篇介绍
# 切换主分支
git checkout master
# 将res分支合并到a
git merge res
上面演示的是本地分支的合并,那么如果我希望将远程的res分支内容合并到master分支,可以如何操作呢
# 将远程res分支合并到当前分支
git merge origin/res
g. 小结
本节主要介绍分支相关的基本操作命令,主要包括如下知识点
- 分支查看:
git branch
: 查看本地分支git branch -a
: 查看本地及远程分支
- 分支创建
git checkout -b new_branch_name
: 创建并切换到新的分支git branch new_branch_name
: 创建新的分支
- 分支切换:
git checkout new_branch
: 切换到新分支(请注意这个和丢弃工作区修改的命令很像哦)
- 分支删除:
git branch -d xxx
: 如果分支有未提交修改需要强删,可以用-D
git push origin --delete xxx
: 删除远程分支
- 分支提交
git push -u origin xxx
- 分支合并
git merge xxx
: 将xxx分支合并到当前分支git merge origin/xxx
: 将远程xxx分支合并到当前分支
6. 标签
关于标签,可能用得不多,但是我们在看一下看远项目的时候,经常会看到release版,各种里程包,当我们完成一个大的稳定的改造之后,可以考虑添加一个tag,记录一下这个”关键“节点,如果别的小伙伴想使用,优先推荐使用这些release版的,而不是最新的(通常见于开源项目的引入使用)
a. 创建标签
# 创建标签v1.0,绑定最新的commit
git tag v1.0
# 指定comitId绑定tag
git tag v1.0 commitId
# 创建带有说明的标签
tag tag -a v1.0 -m '标签说明' commitId
b. 查看标签
# 查看标签列表
git tag
# 查看标签v1.0对应的信息
git show v1.0
c. 推送标签
将本地修改的标签推送到服务器,常见有两种
# 推送1.0tag
git push origin 1.0
# 推送所有本地未推送的tag
git push origin --tags
d. 删除标签
删除标签和删除分支有点类似,都是用-d
# 删除本地分支
git tag -d 0.9
# 删除远程分支,请注意先确保本地的tag已经被删除了
git push origin :refs/tags/0.9
e. 小结
本节主要的知识点在于tag的创建、查询、推送与删除;当我们需要封release版时,建议可以在gitee/github的项目主页中进行操作
- 创建标签
git tag v1.0
: 基于当前的commitId,创建一个v1.0
taggit tag -a v1.0 -m '标签说明' commitId
: 基于指定的commitId创建v1.0
tag,并且可以通过-m
指定标签说明
- 标签查看
git tag
/git tag --list
: 查询当前有哪些标签git show v.10
: 查询v1.0
标签对应的信息
- 标签推送
git push origin v1.0
: 推送本地v1.0
标签到远程git push origin --tags
: 同步本地所有未提交的tag
- 标签删除
git tag -d v1.0
: 删除v1.0标签git push origin :refs/tag/v1.0
: 删除远程v1.0标签(注意执行此操作之前,先删除本地标签)
II. 进阶篇
前面属于基础知识篇,就我个人的看法,除了标签这一块看一看即可,其他的操作,可以说是属于每一个开发者应该掌握的基础知识点;当然仅仅掌握这些基本知识点,在某些时候可能是不够的,接下来将介绍一些可能会提高工作效率的进阶知识点
1. 暂存
a. 实例case
假设我们现在正吭哧吭哧的写新的功能模块,正做得很开心,结果被告知有一个线上bug,需要紧急修复,这个时候就需要把我们做到一半的东西暂存起来,然后切到bug-fix
分支上去修复bug,等bug修复完毕之后,再切回来,并恢复之前的操作
b. 提交本地分支恢复方式
根据上面的场景描述,根据前面学习到基本知识点,我们可以如下操作
# 将所有工作区变动提交到暂存区
git add .
# 将暂存区内容提交到本地分支,注意不要这个时候不要将本地分支的内容同步到服务器
git commit -m 'tmp save'
# 切换bug-fix分支
git checkout bug-fix
# ... 修复bug并提交之后,再恢复之前的feature分支
...
git checkout feature
# 恢复到上一次提交
git reset --soft HEAD^
c. stash方式
上面这一套流程可以满足我们上面的场景,但是不够优雅,在git中,针对上面这种场景有一个更好的命令,那就是stash
同样为了实现上述的case,可以如下操作
# 将所有工作区内容提交到暂存区
git add .
# 暂存
git stash
# 切换bug-fix分支,修复bug
git checkout bug-fix
...
# 切回feature分支,继续业务开发
git checkout feature
# 恢复
git stash pop
d. stash命令小结
上面的case中只演示了两个最常见的stash
命令,接下来将详细说一下在实际的工作中,可能接触的命令
git stash list
: 查看所有的缓存列表git stash
: 将暂存区的所有变动保存起来,这个也是我们最常见的使用姿势,但是有一个缺点,就是不知道这次缓存了什么东西git stash save "说明信息"
: 通过save,在后面加上说明- 下图是通过
git stash list
查看的结果,stash@{1}
是我们没有指定描述的case,后面跟上的是stash时最近的一个commit的提交信息stash@{0}
是我们指定了描述信息的显示结果
git show stash@{num}
显示某次缓存的改动git stash pop stash@{num}
: 恢复之前的某个暂存,并且会删除这次暂存git stash apply stash@{num}
: 同样是恢复,但是与上面的区别在于不会删除暂存中的内容git stash drop stash@{num}
: 丢弃某次暂存git stash clear
: 删除所有的暂存
请注意: stash缓存的是暂存区的内容,所以需要先使用git add .
将工作区的变动提交到暂存区
下面是一个简单的动态图,演示了git stash
的一般使用姿势
2. 解决冲突
关于冲突,可以说是开发者最讨厌遇到的情况了,然而实际的情况是,无论这个项目是只有你一个人开发,还是多人合作开发,冲突多不可避免
case1. 分支合并冲突
每一个git项目都有一个默认的主分支(master分支,最近因为歧视问题,被提议改成main...),通常在其他分支上的修改最终都会合并到master分支上,这里就可能出现合并冲突问题
下面根据一个动态示意图,演示一下冲突合并的case
步骤有点长,下面给出具体的case复现步骤
# 创建并切换到fix分支
✗ git checkout -b fix
# 在fix分支上做一些修改,并提交到分支
✗ echo 'fix some' 1> README.md
✗ git add .
✗ git commit -m 'fix branch'
# 切换master分支,在同样的文件上做修改,并提交到本地分支
✗ git checkout master
✗ echo 'main fix' 1> README.md
✗ git add .
✗ git commit -m 'main fix'
# 分支合并,将本地fix分支的内容,合并到master分支,请注意这个时候会提示冲突
✗ git merge fix
main fix
自动合并 README.md
冲突(内容):合并冲突于 README.md
自动合并失败,修正冲突然后提交修正的结果。
# 这个时候我们可以丢弃合并
✗ git merge --abort
# 也可以选择解决冲突,直接通过vim进去,会看到冲突的地方被 `<<<<<<<<<<<<` 与 `>>>>>>>>` 包裹起来了
✗ vim README.md
# 冲突解决完毕之后,提交
✗ git add .
✗ git commit
case2. 多人协作冲突
多人协作的冲突问题可以说是最常见的case了,我和其他的小伙伴同时修改了某个文件,而其他的小伙伴又是先与我提交的,这个时候,再同步最新代码的时候就会出现冲突问题
请注意上图中的上下两个窗口分属本地两个不同git-study
工程,这个冲突主要是我们在提交之前,同步远程信息时,提示冲突了,一般的解决思路也比较明确,根据冲突文件,找到冲突的地方,fix掉,然后git add .
+ git commit
即可
请注意,上面合并完毕之后,除了我们之前的commit之外,还会新增了一个merge的commit
小结
这一小节主要介绍了常见的两种导致冲突的case,一般来讲解决冲突依然是需要靠我们人工去选取最终保留的代码
一般推荐的使用姿势
- 提交代码之前,先拉一下最新改动:
git pull
- 如有冲突,修改完毕之后,记得执行
git commit
来提交冲突的fix - 如不想保存冲突合并,可以执行
git merge --abort
丢弃合并
3. rebase
a. 使用背景
在上面介绍多人协作导致的冲突的时候,解决完之后,发现最终会新怎给一个merge的commit,也就是说我们的这一次提交会有两个commit(一个是我们之前的准备提交的内容,一个是合并冲突解决的commit)
此外,我们再看一下上面冲突解决之后的分支情况
git log --graph --pretty=oneline --abbrev-commit
除了上面命令行的查看方式之外,也可以直接在gitee/github网页上查看分支网络图,可能更加直观
那么我们的问题来了
- 我们是否可以只保留一个commit
- 我们是否可以让git的提交历史是一条直线,而不出现交叉呢
b. reabse使用
同样是上面的case,某个小伙伴修改readme.md
并提交了rebase test
commit;然后我们同样修改readme.md
,但是注意这次同步最新代码使用的是git pull --rebase
上面的动态有点长,下面简单的说一下关键点
# 本地修改,并提交到本地分支
git add .
git commit -m 'main branch save'
# 注意这里同步使用命令
git pull --rebase
# 因为发生冲突,这个时候可以看到我们当前的工作区不在master分支上了
# 我们需要在新的分支上解决冲突,解决完毕之后,同样的提交
git add .
git commit
# 提交完毕之后,我们希望回到master分支,注意这里不是使用 git checkout master来切换分支, 而是使用下面的命令
git rebase --skip
# 如果我们不希望保留这次的合并,可以执行以下命令丢弃
git rebase --abort
# 切换回master分支之后,我们查看当前log,和分支网络图
git log --graph --pretty=oneline --abbrev-commit
c. 小结
一般来讲我们推荐在提交之前先同步最新代码,这个时候使用git pull --rebase
可能是一个更好的选择
当出现合并冲突时,会进入一个临时的分支,这个时候我们需要做的是下面四步
- fix 冲突
git add
/git commit
: 提交冲突的解决git rebase --skip
: 冲突已解决,回到之前的分支git push
: 同步本次修改
为什么推荐使用rebase
- 分支历史提交为一条直线,不会分叉,更直观
- 一个commit,对于诸如使用
gerrit
来做代码权限管理时,更加友好
可不可以不用rebase
- rebase看起来有点麻烦,这个知识点我个人认为并不属于基本功能,不掌握也不会影响日常的工作流程
4. gitignore
如果我的项目里面并不是所有的内容都需要提交,然而我又特别喜欢通过git add .
来讲所有工作区内容提交到暂存区,这个时候咋办?
- 借助
.gitignore
文件来排除需要提交的文件
a. 规则说明
在项目根目录下,新增文件.gitignore
- 以斜杠/开头表示目录;
- 以星号*通配多个字符;
- 以问号?通配单个字符
- 以方括号[]包含单个字符的匹配列表;
- 以叹号!表示不忽略(跟踪)匹配到的文件或目录;
b. 实例说明
# 过滤logs文件夹,及文件下所有的文件
/logs
# 所有以.开头的文件都过滤掉
.*
# .gitignore 文件不忽略
!.gitignore
说明:在我们新建.gitignore
之前,一些可以被忽略掉的文件已经进入暂存区,可以怎么处理呢?
git rm -r --cached 文件夹
: 针对文件夹,递归删除git rm --cached 文件
: 针对文件,指定删除
5. 分子合并的三种姿势
在基础篇中我们介绍了直接使用git merge
来合并分支的case,但是一般不建议直接使用这种方式,更过的是推荐加上参数--no-ff
这里我们将简单的介绍下合并的三种可选方式
fast-forward
: 默认方式,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,当分支删除时会丢失merge信息squash
: 将分支上的所有变动合并带过来,不提交,需要手动添加一次commit
来指定提交信息no-ff
: 在提交的时候,会创建一个merge的commit信息,然后合并分支
上图给出一个实例演示下三种合并方式的区别
fast-forward
直接合并,无merge关键节点squash
: 分支所有变动合并过来,需要额外的手动添加commit
提交到当前分支(对应分支的所有commit没有)no-ff
: 合并并创建一个merge
的commit信息(推荐使用这种方式,有对应分支的历史提交,有合并节点)
借用网上的一张图,来表示他们三个的区别
6. 项目配置
在上面最开始介绍环境配置的时候,我们一般会设置一个全局的用户名/邮箱,然而实际情况,公司内的项目提交需要用公司内网邮箱;而我自己的git项目,希望用私人邮箱,这个时候全局的配置就不适合了
针对这种case,可以如下处理
# 进入配置文件
✗ vim .git/config
# 新增下面的配置,保存并退出
[user]
name = 一灰灰
email = yihuihuiyi@gmail.com
当我们再次进行提交时,查看一下git log
(上面这个也演示了为啥同一个git项目,就我一个参与者,为啥会有多个用户列表了)
7. 删除文件及历史记录
据说因为github导致的密钥泄露问题比较普遍,我们知道git的强大之处在于它可以记录你的所有提交,可以追溯某个文件从创建到最终的销毁的所有历史,因此当你不小心将某些敏感信息提交到git仓库之后,即便你马上发现并删除,但是别人依然可以“顺藤摸瓜”找到
那么当我错误的提交了一个敏感文件到git仓库,有没有挽救办法呢,还是说只能删库重来?
上图演示了我们在gitee上删除这个文件之后,依然可以通过历史的commit找到对应的提交内容
下满是一个解决办法
git filter-branch -f --tree-filter 'rm -rf senstive.txt' HEAD
# 强制提交, 非特殊情况,不建议使用这个命令
git push origin --force
当我们再次进行查看时,在历史的提交中也找不到senstive.txt
文件了
8. 统计
最后给一个小工具,统计一下自己过去一年某个项目的工作量
git log --author="$(git config --get user.name)" --before='2020-12-31 23:59:59' --after='2020-01-01 00:00:00' --pretty=tformat: --numstat | awk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }'
下图给出了我quick-media从诞生到现在的所有改动情况(代码删得多,说明时不时会重构一把😝)
III. 归纳总结
本篇作为程序猿必备技能第一篇,git可以说是每个小伙伴都应该掌握的知识点,本文划分了基础与进阶两段,内容都不算难,花10-15分钟读完之后,基本上就可以了解git怎么玩了
因为内容篇幅较长,所以我们这里也敲一敲黑板,画一下重点
1. 同步修改提交三把斧
日常业务工作中,最最常见,最最基础的步骤
# 提交本地修改
git add .
git commit -m 'save'
# 同步最新代码
git pull --reabse
# 冲突时,先解决冲突
fix conflict
git add .
git commit
# 解决完冲突,回到之前的分支
git rebase --skip
# 没有冲突/or冲突已解决时,直接提交
git push
2. 查看变动
当我们想知道哪些文件被修改,修改了啥时,常用的几招
# 可以查看工作区 + 暂存区的所有变动
git status
# 查看工作区的变动
git diff
# 查看暂存区的变动
git diff head^
3. 历史查看
通过git log
可以查看历史提交,通过log,可以做很多事情,下满只给常用的几种
# 查看git历史
git log
# 一行展示,方便阅读
git log --pretty=oneline
# 图方式查看历史变动情况
git log --graph --pretty=oneline
此外还有一个git reflog
也有可能会用到,查看本地仓库的变动
4. 分支
分支的几大操作,无非创建,切换,查看,删除以及合并
- 创建:
git branch newBranch
- 创建并切换:
git checkout -b newBranch
- 切换分支:
git checkout newBranch
- 分支列表:
git branch
/git branch -a
- 删除分支:
git branch -d/D branchName
- 合并分支到当前分支:
git merge newBranch
- 合并远程分支到当道分支:
git merge --no-ff origin/newBranch
关于分支合并,推荐使用--no-ff
来替代默认的fast-forward
合并方式
5. 版本回退与撤销修改
使用reset
来实现版本回退;使用checkout
来撤销修改
- 回退到指定的commit:
git reset --soft/hard commitId
soft
; 表示保留这个commitId之后的所有修改hard
: 完全恢复commitId这个时候的状态
- 取消暂存:
git reset HEAD .
暂存区所有变动回到工作区 - 撤销工作区修改;
git checkout .
6. 标签
标签更多的是立flag,打里程包,方便给其他的小伙伴稳定的引入
- 创建标签
git tag v1.0
: 基于当前的commitId,创建一个v1.0
taggit tag -a v1.0 -m '标签说明' commitId
: 基于指定的commitId创建v1.0
tag,并且可以通过-m
指定标签说明
- 标签查看
git tag
/git tag --list
: 查询当前有哪些标签git show v.10
: 查询v1.0
标签对应的信息
- 标签推送
git push origin v1.0
: 推送本地v1.0
标签到远程git push origin --tags
: 同步本地所有未提交的tag
- 标签删除
git tag -d v1.0
: 删除v1.0标签git push origin :refs/tag/v1.0
: 删除远程v1.0标签(注意执行此操作之前,先删除本地标签)
7. stash暂存
通过stash将当前的工作内容暂存起来,然后去做其他的事情;做完之后再回来接着之前的工作继续
实际的工作中可能用得不多,但是用的好的话,可以省很多事情
git stash list
: 查看所有的缓存列表git stash
/git stash save "说明信息"
: 暂存git show stash@{num}
显示某次缓存的改动git stash pop stash@{num}
: 恢复之前的某个暂存,并且会删除这次暂存git stash apply stash@{num}
: 同样是恢复,但是与上面的区别在于不会删除暂存中的内容git stash drop stash@{num}
: 丢弃某次暂存git stash clear
: 删除所有的暂存
8. Git操作图
最后附上一个神图,介绍了各种git命令, 原文点击下载
9 . 配套讲解视频
为了更友好的演示git的基本使用,特意录制了一个视频,由于是第一次录制,效果不是特别好,凑合的话还是能看,请各位大佬轻喷
对应的视频地址如: 程序猿基本功系列:项目管理工具GIT全解