Git 学习笔记
前言
最近用 GitHub 搭建了个人博客,顺便再回顾一下之前了解过但是没熟练掌握的 Git ,本篇主要是记录关于 Git 的一些命令和技巧,学习途径——廖雪峰Git教程,详细教程可以阅读廖雪峰Git教程。
git 新更改: git checkout
可替换命令 git switch
和 git restore
,这里的笔记以新更改为主。
基本配置
–global:设置全局变量,局部变量则无需
--global
参数。
设置用户信息
1 | git config --global user.name "用户名" |
查看配置信息
1 | git config --global user.name |
Git 基础操作
初始化 Git 仓库
工作区(workspace):
- 未跟踪(untracked):新创建文件。
- 未暂存(unstaged):修改已有文件。
1 | git init |
把文件添加到仓库
工作区(workspace) –> 暂存区(index)
已暂存(staged):提交到仓库之前的缓存区。
1 | git add <file> |
把文件提交到仓库
暂存区(index) –> 本地仓库(repository)
说明:如果把文件提交到仓库后,工作区(workspace)无操作,则暂存区(index)是干净的。
1 | git commit -m "本次提交的说明" |
查看文件状态
1 | git status |
查看文件不同
git diff
:是查看 working tree 与 index 的差别的。git diff --cached
:是查看 index 与 repository 的差别的。git diff HEAD
:是查看 working tree 和 repository 的差别的。其中:HEAD 代表的是最近的一次 commit 的信息。
1 | git diff <file> |
显示提交日志
options:
--all
:显示所有分支。--pretty=oneline
:将提交信息显示为一行。--abbrev-commit
:使得输出的commit更简短。--graph
:以图的形式显示。
1 | git log [options] |
查看历史命令
1 | git reflog |
撤销修改
无参:撤销工作区(workspace)的修改。
--staged
:撤销上传到暂存区(index)。
1 | git restore [--staged] <file> |
回退版本
回退上个版本
回退多个版本可以把
^
换成~<回退版本数>
。
1 | git reset --hard HEAD^ |
回退到指定版本
1 | git reset --hard <commit id> |
删除文件
注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!
文件修改后,与版本库不同时,再删除,此时options:
--cached
:仅删除暂存区里的文件。此时 commit ,会出现工作区存在修改后的删除文件,而版本库此文件被删除。
-f
:强制删除[工作区+暂存区]。此时 commit ,会出现工作区和版本库此文件都删除。理解:
rm <file>
可以在任何文件夹都可以用,包括不是git仓库的地方,是用来删除文件。如果用在git仓库里,则可以视为删除工作区的文件。
git rm <file>
只能在git仓库里使用,是用来删除(工作区+暂存区)的文件用的,如果此文件被修改过则要加入参数-f
来删除(工作区+暂存区)的文件。
git rm --cached <file>
如果想仅删除暂存区里的文件可以用此命令,它不会删除工作区中的文件。建议:
用
rm
或者鼠标点击的方式删除文件。用命令
git rm <file>
确认删除文件。用命令
git restore <file>
返回被删除的文件(无论文件修改与否,返回的都是未修改前的文件)。
1 | git rm [options] <file> |
关联远程库 GitHub
在新建空白 GitHub 仓库时,也会生成可以关联 git 的命令。
repo-name:克隆仓库名。
user-name:克隆仓库的用户名。
server-name:基本上是 github.com。
1 | git remote add origin git@server-name:path/repo-name.git; |
推送到 GitHub
把本地库的内容推送到远程,用
git push
命令,实际上是把当前分支 master 推送到远程。由于远程库是空的,我们第一次推送 master 分支时,加上了
-u
参数,Git 不但会把本地的 master 分支内容推送的远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令。origin:远程库的名称。
本地仓库推送到远程仓库
1 | git push <远程仓库名> <本地分支名>:<远程分支名> |
初次推送
1 | git push -u origin master |
非初次推送
1 | git push origin master |
远程库操作
查看远程库
1 | git remote -v |
删除远程库
注意:此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到 GitHub ,在后台页面找到删除按钮再删除。
1 | git remote rm <远程库名称> |
SSH 克隆远程库
repo-name:克隆仓库名。
user-name:克隆仓库的用户名。
dir:要克隆到本地的文件目录,默认是”./“。
1 | git clone git@github.com:user-name/repo-name.git [dir] |
HTTPS 克隆远程库
https-link:克隆仓库的
https
链接。dir:要克隆到本地的文件目录,默认是”./“。
1 | git clone https-link [dir] |
分支管理
新建分支
1 | git branch <分支名> |
切换分支
-c
: 新建分支并切换到该分支。
1 | git switch [-c] <分支名> |
查看当前分支
当前分支会带”*“号。
1 | git branch |
合并分支
git merge
命令用于合并指定分支到当前分支。Fast-forward:合并是“快进模式”,也就是直接把当前分支指向要合并分支的当前提交,所以合并速度非常快。但这种模式下,删除分支后,会丢掉分支信息。
--no-ff
:表示禁用 Fast forward,从分支历史上就可以看出分支信息。
-m
:合并要创建一个新的commit。分支策略:
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,
master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在
dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;你和你的小伙伴们每个人都在
dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。
1 | git merge [options] <要合并到当前分支的分支名> |
删除分支
-d
:删除分支。
-D
:强制删除,用于没有合并的分支。
1 | git branch -d/-D <分支名> |
BUG 分支
- 封存当前工作现场(封存已跟踪文件)。
1 | git stash |
- 查看封存的工作现场。
1 | git stash list |
恢复封存的工作现场
- 用
git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除。
1
git stash apply <恢复编号>
1
git stash drop <恢复编号>
- 用
git stash pop
,恢复的同时把stash内容也删了。
1
git stash pop
- 用
复制已有 bug 分支(如果是未提交的工作现场,要先封存或提交,才能复制已有 bug 分支)。
1 | git cherry-pick <bug 版本号> |
多人协作
因此,多人协作的工作模式通常是这样:
- 首先,可以试图用
git push origin <branch-name>
推送自己的修改; - 如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并; - 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后要
add
和commit
后,再用git push origin <branch-name>
推送就能成功!
如果 git pull
提示 no tracking information
,则说明本地分支和远程分支的链接关系没有创建,用命令 git branch --set-upstream-to <branch-name> origin/<branch-name>
。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
整理分支线
特点:把分叉的提交历史“整理”成一条直线,看上去更直观。缺点是本地的分叉提交已经被修改过了。
使用:本地分支过时与远程分支。
1 | git rebase |
标签管理
创建标签
- 指定分支打标签,首先要切换到指定分支。
- commit id:指定版本号创建标签。
- options:用
-a
指定标签名,-m
指定说明文字。
1 | git tag [options] <标签名> [commit id] |
查看标签
- 查看所有标签
1 | git tag |
- 查看标签信息
1 | git show <标签名> |
删除标签
- 删除标签
1 | git tag -d <标签名> |
- 删除远程标签
1 | git push origin :refs/tags/<标签名> |
推送标签
- 推送指定标签
1 | git push origin <标签名> |
- 推送全部标签
1 | git push origin --tags |
忽略特色文件
在Git工作区的根目录下创建一个特殊的 .gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
不需要从头写 .gitignore
文件,GitHub 已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore。
忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如 Java 编译产生的
.class
文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
如果你想添加被忽略的文件,可以用 -f
强制添加到 Git;或者你发现,可能是 .gitignore
写得有问题,需要找出来到底哪个规则写错了,可以用 git check-ignore
命令检查:
把指定文件排除在 .gitignore
规则外的写法就是 !
+ 文件名。
配置别名
配置Git的时候,加上
--global
是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。每个仓库的Git配置文件都放在
.git/config
文件中。当前用户的Git配置文件放在用户主目录下的一个隐藏文件
.gitconfig
中。
- 配置命令
1 | git config --global alias.<别名> <原名> |
- 配置一个
git last
,让其显示最后一次提交信息
1 | git config --global alias.last 'log -1' |
- 查看日志配置别名
1 | git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" |
Git 技巧
使用命令
git add <file>
,注意,可反复多次使用,添加多个文件;使用命令
git commit -m <message>
,完成提交文件到本地仓库。
要随时掌握工作区的状态,使用
git status
命令。如果
git status
告诉你有文件被修改过,用git diff
可以查看修改内容。HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
。穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本。要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本。每次修改,如果不用
git add
到暂存区,那就不会加入到commit
中。撤销修改操作:
- 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令
git restore <file>
。 - 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令
git restore --staged <file>
,就回到了场景1,第二步按场景1操作。 - 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,回退版本,不过前提是没有推送到远程库。
- 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令
命令
git rm
用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。建议的删除操作:
用
rm
或者鼠标点击的方式删除文件。用命令
git rm <file>
确认删除文件。用命令
git restore <file>
返回被删除的文件(无论文件修改与否,返回的都是未修改前的文件)。
要关联一个远程库,使用命令
git remote add origin git@server-name:path/repo-name.git
;关联一个远程库时必须给远程库指定一个名字,
origin
是默认习惯命名;关联后,使用命令
git push -u origin master
第一次推送master分支的所有内容;此后,每次本地提交后,只要有必要,就可以使用命令
git push origin master
推送最新修改;要克隆一个仓库,首先必须知道仓库的地址,然后使用
git clone
命令克隆。Git支持多种协议,包括
https
,但ssh
协议速度最快。Git鼓励大量使用分支:
- 查看分支:
git branch
- 创建分支:
git branch <name>
- 切换分支:
git checkout <name>
或者git switch <name>
- 创建+切换分支:
git checkout -b <name>
或者git switch -c <name>
- 合并某分支到当前分支:
git merge <name>
- 删除分支:
git branch -d <name>
- 当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。用
git log --graph
命令可以看到分支合并图。
- 查看分支:
- 合并分支时,加上
--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward
合并就看不出来曾经做过合并。 - bug 分支
- 修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除;
- 当手头工作没有完成时,先把工作现场
git stash
一下,然后去修复 bug ,修复后,再git stash pop
,回到工作现场; - 在 master 分支上修复的 bug ,想要合并到当前 dev 分支,可以用
git cherry-pick <commit>
命令,把 bug 提交的修改“复制”到当前分支,避免重复劳动。
- 开发一个新feature,最好新建一个分支;如果要丢弃一个没有被合并过的分支,可以通过
git branch -D <name>
强行删除。 - 多人协作
- 查看远程库信息,使用
git remote -v
; - 本地新建的分支如果不推送到远程,对其他人就是不可见的;
- 从本地推送分支,使用
git push origin branch-name
,如果推送失败,先用git pull
抓取远程的新提交; - 在本地创建和远程分支对应的分支,使用
git switch -c branch-name origin/branch-name
,本地和远程分支的名称最好一致; - 建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
; - 从远程抓取分支,使用
git pull
,如果有冲突,要先处理冲突。
- 查看远程库信息,使用
rebase
操作可以把本地未 push 的分叉提交历史整理成直线;rebase
的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。- 标签管理
- 命令
git tag <tagname>
用于新建一个标签,默认为HEAD
,也可以指定一个 commit id; - 命令
git tag -a <tagname> -m "blablabla..."
可以指定标签信息; - 命令
git tag
可以查看所有标签; - 命令
git push origin <tagname>
可以推送一个本地标签; - 命令
git push origin --tags
可以推送全部未推送过的本地标签; - 命令
git tag -d <tagname>
可以删除一个本地标签; - 命令
git push origin :refs/tags/<tagname>
可以删除一个远程标签。
- 命令
- 在GitHub上,可以任意Fork开源仓库;自己拥有Fork后的仓库的读写权限;可以推送pull request给官方仓库来贡献代码。
- 忽略某些文件时,需要编写
.gitignore
;.gitignore
文件本身要放到版本库里,并且可以对.gitignore
做版本管理!
📌最后:希望本文能够给您提供帮助,文章中有不懂或不正确的地方,请在下方评论区💬留言!