git使用 -- 潘登同学的git使用笔记
git是目前最流行的版本控制系统。
- 版本控制系统:记录文件或代码的变化,以便于追踪、回滚、比较等。
- 分布式:每个开发者都可以有完整的版本库,可以方便地进行协作。
Git的安装与配置
- 安装Git
下载Git安装包,并安装。git官网:https://git-scm.com/downloads 一路next即可。
查看是否安装成功:在命令行中输入git,如果出现git的帮助信息,则说明安装成功。
git --version
- 配置Git
当安装完成后,需要进行一些配置,以便使用Git。因为每次提交代码时,Git都需要记录提交者的姓名和邮箱,所以需要进行配置。
git config --global user.name "your name"
git config --global user.email "your email"
--global
参数表示全局配置,也就是对当前用户起作用。
配置完后,可以使用git config --list
命令查看当前的配置信息。或者在.gitconfig
文件中查看。
Git基本命令
Git初始化本地仓库
cd到你要创建仓库的目录,然后执行:
git init
这将创建一个名为.git
的目录,这个目录是Git用来存放版本库的。
Git工作区、暂存区、版本库
- 工作区:就是你在电脑里能看到的目录,比如
D:\project\test
。 - 暂存区:英文叫stage或index,它是Git的暂存区域,临时保存你对文件所做的改动。
- 版本库:工作区有一个隐藏目录
.git
,这个目录是Git的版本库,用来保存所有版本的历史记录,包括提交过的版本和暂存的改动。
Git跟踪文件
首先确定工作区中有文件
git status
如果没有文件,则执行:
git add 文件名
跟踪文件后,Git会把文件暂存到暂存区,从而git可以跟工作区、本地仓库之间进行交互。
untracked files
表示工作区中有文件没有被跟踪。to be committed
表示暂存区中有文件等待提交。
git提交文件
git commit -m "提交说明"
提交后,执行git status
命令,可以看到nothing to commit, working tree clean
表示暂存区已经清空,工作区没有未提交的改动。
Git修改文件
- 修改文件
修改文件后,需要先跟踪文件:
git add .
- 提交修改
git commit -m "提交说明"
查看提交历史:
git log
# 可以加上--oneline参数,查看简短的提交历史
git log --oneline
Git删除文件
删除文件有两种方式,第一种是直接删除文件,然后要加入缓存区再提交
rm 文件名
git add .
git commit -m "删除文件"
第二种是使用git直接提交删除操作(减少了一步)
git rm 文件名
git commit -m "删除文件"
git撤销操作
之前保存了,然后做了修改操作,发现修改不满意,想撤销到上一个版本,可以使用git restore
命令。
# 将文件从暂存区恢复到工作区,用于丢弃本地修改。
git restoe 文件名
git取消暂存
如果做了修改操作并已经将文件暂存到暂存区,但是又不想提交,想恢复到上一个暂存区版本,可以使用git restore --staged
或者git reset -- file
命令。
git restore --staged . # 用于恢复所有暂存区文件
git reset -- . # 用于恢复所有暂存区文件 (二选一即可)
git restore . # 用于恢复所有文件(恢复到工作区)
git跳过暂存区
为了简化提交操作,可以使用git commit -a
命令,这将自动把所有已经跟踪过的文件暂存起来一并提交,跳过了git add
命令。
git commit -a -m "提交说明"
提示: 使用-a
跳过git add
步骤的前提是这些待提交的文件必须已经被跟踪过,-a
不会自动将未跟踪的文件变为跟踪文件。
为了简化撤销操作,可以使用git checkout HEAD .
命令,这将把暂存区的文件撤销掉,回到工作区。
git checkout HEAD -- 文件名
git checkout HEAD . # 用于撤销所有文件(回到工作区)
git版本回退
# 回退到上一个版本
git reset --hard HEAD^
# 回退到指定版本
git reset --hard 版本号
HEAD表示当前版本,HEAD^
表示上一个版本,HEAD^^
表示上上一个版本,依次类推。
也可以用数字指定回退版本,比如git reset --hard HEAD~10
表示回退到前10个版本。
可以用git reflog
命令查看命令历史,以便确定要回退到哪个版本。 版本号只需要前4位即可。
版本回退会使得暂存区和工作区的文件都回到上一个版本,提交记录也会被删除。
git撤销提交
如果是想回到上一个版本,但是又不想删除提交记录,可以使用git revert
命令。
git revert
命令会在版本库中创建一个新的提交,撤销之前的提交,保留提交说明。
相当于在版本库中创建了一个新的提交,(就好像)回到了之前的版本。
git revert HEAD # 撤销最后一次提交
git revert 版本号 # 撤销指定版本的提交
Git常用命令
git忽略文件
有些文件不需要纳入版本管理,比如日志文件、缓存文件等。可以创建一个.gitignore
文件,列出要忽略的文件。
格式规范
- 所有空行或者以
#
开头的行都会被忽略。 - 可以使用标准的glob模式匹配。
- 匹配模式最后跟反斜杠
(/)
说明要忽略的是目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上感叹号
(!)
。
glob模式匹配规则:
*
匹配任意字符串,?
匹配单个字符,[abc]
匹配a
、b
、c
中的任意一个字符。**
匹配多级目录。{}
匹配括号内的任意模式。
# 忽略所有.log文件
*.log
# 忽略所有logs文件和目录,包括多级路径下的logs目录,logs目录下的文件也会被忽略
logs/
# 忽略当前目录下的 logs 目录
/logs
# 忽略 a/foo a/b/foo /foo等 目录下的文件
**/foo
git比较文件差异
# 比较工作区和暂存区的差异
git diff
# 比较暂存区和版本库的差异
git diff --cached
# 比较两个版本之间的差异
git diff 版本号1 版本号2
# 比较工作区和版本库的差异
git diff HEAD
git代码托管平台
通常进行多人协作开发时,需要一个代码托管平台,比如GitHub、GitLab等。
- GitHub:https://github.com/
- 也可以自己搭建Git服务器,比如GitLab。
git本地添加远程仓库
# 先在本地初始化仓库
git init
# 添加远程仓库
# git remote add <name> <url>
git remote add origin https://github.com/username/repository.git
# 查看远程仓库信息
git remote
# 删除远程仓库 只是解除本地与远程仓库的关联
# git remote rm <name>
git remote rm origin
# 推送本地仓库内容到远程仓库
# git push <remote> <branch>
git push origin master
# 拉取远程仓库内容到本地仓库
# git pull <remote> <branch>
git pull origin master
git克隆与推送
# 克隆前不要求初始化本地仓库
# 克隆远程仓库到本地 默认名称为 origin
# git clone <url>
git clone https://github.com/username/repository.git
# 推送本地仓库内容到远程仓库
# git push <remote> <branch>
git push origin master
# 后续直接使用 git push 即可 origin master等信息已经记录了
git拉取与合并
# 拉取远程仓库内容到本地仓库
# git pull <remote> <branch>
git pull origin master
# 后续使用 git pull 即可
# 使用git pull拉取前确保设置了跟踪信息
# git branch --set-upstream-to=<remote>/<branch> <current_branch>
git branch --set-upstream-to=origin/master master
git抓取
git fetch命令用于从远程仓库获取最新数据,但不会自动合并到本地仓库。当准备好了自己本地仓库和远程仓库的同步,就可以使用git merge命令进行合并。
# 从远程仓库抓取最新数据
# git fetch <remote> <branch>
git fetch origin master
# 后续使用 git fetch 即可
# 合并远程仓库的最新数据到本地仓库
# git merge <remote>/<branch>
git merge origin/master
git合并冲突
冲突是指两个或多个分支在同一文件中进行了不同的修改,导致git无法自动合并。
解决方案:
- 先拉取远程仓库的最新数据,然后手动合并。在冲突的文件中会有HEAD和分支的不同内容,需要手动解决冲突。(把那些多余的符号也要删掉)
所以要养成习惯,在推送代码前先拉取最新数据,然后手动合并冲突。
git分支
git中的分支,本质上是指向提交对象commit的可变指针。git会使用master分支作为默认分支,其他分支都基于master分支。分支在每次提交的时候都会向前移动。在进行若干次提交后,其实已经有了一个指向最后一次提交对象的分支。
- 基于当前分支创建新分支 这会在(当前分支指向的commit对象)上新建一个新的分支指针。
# git branch <name>
git branch testing
注意:不同分支可以指向同一个commit对象,但不能有相同的提交记录。
HEAD指针
HEAD指针是一个指向当前工作中的本地分支的指针。如果我们只有一个默认的mater分支,那么HEAD指针指向master分支。
如果有多个分支,切换分支时,HEAD指针会自动移动到目标分支。
# 切换到testing分支
git checkout testing
当在testing分支上进行了提交,HEAD指针会自动移动到testing分支指向的提交对象。
为什么要使用分支
一般项目中会有三个分支:master分支、dev分支、feature分支。
- master分支:主分支,用于发布稳定版本。经过测试的提交都应该合并到master分支。
- dev分支:开发分支,用于开发新功能。或者仅用于临时测试,不稳定。
- feature分支:功能分支,用于开发新功能。从dev分支上拉取,开发完成后合并回dev分支。(名称一般由开发的功能名称加上feature前缀构成)
工作场景:开发人员在某个功能分支正在编写代码,突然接到一个电话说线上有个很严重的问题需要紧急修补,这个时候我们面临的问题:当前的功能代码不能提交到线上,所以不能在当前分支进行bug修复。
解决方案:
- 首先,返回到原先已经发布到线上的稳定版本master分支。
- 然后,创建一个新的分支hotfix分支,从master分支上拉取最新代码。
- 然后,在hotfix分支上进行紧急修复。通过测试后,合并回master分支。
- 最后,切换回原先的功能分支,继续开发。
git分支管理
创建分支
# 创建新分支前 先保证有提交对象
git commit -m "提交说明"
# 此时master分支指向最新提交对象
# 创建新分支
# git branch <name>
git branch testing
查看分支
其中分支前面带*
号表示当前分支。
# 查看所有分支
git branch
# 查看所有分支的最后一次提交
git branch -v
切换分支
# 切换到testing分支
git checkout testing
注意:切换分支,本地工作区的文件会被暂存区的文件覆盖。
新建并切换到新分支:
# 创建并切换到新分支
# git checkout -b <name>
git checkout -b feature/test
删除分支
# 删除testing分支
# git branch -d <name>
git branch -d testing
合并分支
# 切换到新分支
git checkout feature/test
# 进行代码编辑,在新分支上提交内容
git commit -m "提交说明"
# 切换回master分支
git checkout master
# 将新分支合并到master分支
# git merge <name>
git merge feature/test
最后删除没用的分支:
# 删除feature/test分支
git branch -d feature/test
合并分支冲突
有时候合并操作不会如此顺利。如果在不同分支中都对同一个文件进行了不同的修改,那么git无法自动合并,会出现合并冲突。
# 切换到master分支
git checkout master
# 合并dev分支
git merge dev
# 出现合并冲突,需要手动解决冲突
# 编辑冲突文件,删除多余的符号
# 解决冲突后,提交
git commit -am "提交说明"
git储藏
有的时候,我们在开发过程中,会有一些临时性的修改,比如测试代码,或者一些小的改动。这些修改并不一定要提交,但是又不想丢失。这时候,我们就可以使用git stash命令进行储藏。
# 储藏当前工作区的修改
git stash
# 切换到别的分支
git checkout master
# 查看储藏列表
git stash list
# 切换回原先的分支
git checkout dev
# 恢复储藏
git stash apply
git远程分支
远程分支(remote branch )是对远程仓库中的分支的索引。它们是一些无法移动的本地分支,远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置。
我们用 (远程仓库名)/(分支名) 这样的形式表示远程分支。在本地我们只能移动本地master分支,不能移动远程分支origin/master。
- 从远程仓库克隆项目到本地
- 在本地master分支修改内容,提交后,本地master分支移动,origin/master分支保持不变。
- 只有跟服务器通信,远程分支origin/master分支才会移动,比如其他人往远程仓库推送了代码,则远程仓库中,master分支向前移动,我们可以通过 git fetch 获取远程仓库库的最新数据。
- 通过 git merge orgin/master 将远程分支的变更合并到本地master分支。
创建远程仓库分支
从本地向远程仓库推送分支
- 在本地新建分支 feature_user
- 推送本地分支到远程仓库
- 其他人通过 git fetch 获取远程仓库库的最新数据
# 推送本地分支到远程仓库
# git push <remote> <branch> git push 远程仓库名 本地分支名:远程分支名 远程分支名跟本地分支名相同,可以采用简写
git push origin feature_user
# 其他人通过 git fetch 获取远程仓库库的最新数据
git fetch origin
# 通过远程分支创建本地分支 (先git fetct)
# git checkout -b <name> <remote>/<branch>
git checkout -b feature_user origin/feature_user
注意:
- 通过
git checkout -b <name> <remote>/<branch>
创建本地分支时,本地分支会自动与远程分支建立追踪关系。 - 也可以先在本地新建feature_user分支,然后 git fetch 获取最新数据,再通过
git merge origin/feature_user
手动合并到本地分支,但需要手动跟踪远程分支。设置跟踪分支git branch --set-upstream-to=origin/develop develop
也可以直接在GitHub网站上创建远程分支,然后推送本地分支到远程仓库。
删除远程分支
当我们的某个分支已经合并到master分支,并且不再需要保留时,我们可以删除远程分支。可以直接在GitHub网站上删除远程分支,也可以使用命令行删除。
# 删除远程分支
# git push <remote> --delete <branch>
git push origin --delete feature_user
注意:删除远程分支后,会将本地远程分支这个指针跟服务器上面对应的分支删除掉,本地分支不会被删除。
Git其他命令
SSH协议
SSH协议是一种网络协议,用于在两台计算机之间进行安全的远程登录。与https协议不同,https是通过用户名和密码进行认证,而SSH协议是通过密钥进行认证。
- 什么是SSH协议
SSH协议是一种网络协议,用于在两台计算机之间进行安全的远程登录。它使用公钥加密技术,允许用户在不安全的网络中安全地进行远程登录。利用SSH协议可以有效防止中间人攻击、数据篡改、数据泄露等安全风险。
- 如何生成SSH密钥
# 在命令行cmd中输入以下命令,生成SSH密钥
ssh-keygen -t rsa -C "your email"
# 然后回车,会出现一系列提示,按回车键继续。
# 最后会在用户目录下生成.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个文件是SSH密钥。
然后把公钥id_rsa.pub的内容复制到GitHub、GitLab等代码托管平台的SSH公钥设置中。
然后复制仓库的SSH地址,使用SSH协议克隆仓库:
# 克隆仓库
# git clone <ssh_url>
git clone git@github.com:username/repository.git
git标签
- 什么是标签?
- 标签可以是一个对象(带注解标签),也可以是一个简单的指针(不带注解标签),用来标注某次提交对象。
- 如果只是一个简单的指针,则它就相当于一个不会移动的分支。
- 如果是一个对象,则除了保存指向的提交对象的信息之外,还会保存是谁打的标签,什么时间,还可以保存注解信息。(推荐使用)
- 为什么要使用标签?
- 我们可以为重要的版本(某个里程碑)打上标签,相当于为这次提交记录指定一个别名,方便提取文件。比如人们在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做。
- 标签跟分支的区别?
- 分支会跟着我们的提交移动,指向最新的提交对象,但是标签不会移动,它就是指向某个固定的提交对象
新建标签:git tag -a <name> -m "标签说明"
- -a:创建一个带注解的标签
- -m:添加标签说明
默认情况下,标签指向最新提交对象,如果要指定标签指向的提交对象,可以指定提交对象ID。git tag -a <name> <commit_id> -m "标签说明"
# 新建一个标签
git tag -a v1.0 -m "版本1.0"
# 查看所有标签
git tag
# 查看某个标签的详细信息
git show v1.0
# 删除标签
# git tag -d <name>
git tag -d v1.0
# 推送标签到远程仓库
# git push <remote> <tag>
git push origin v1.0
通过标签获取对应版本(检出)git checkout -b 本地分支名 标签名
# 获取v1.0版本
git checkout -b test_dev v1.0
在VSCode中使用Git
VSCode是微软推出的开源代码编辑器,它内置了Git插件,可以方便地使用Git进行版本控制。
- 安装Git插件
- 初始化仓库
- 暂存文件 (点击文件右侧的加号)
- 提交文件
- 推送到远程仓库
推送前先拉取,解决冲突,然后再推送。 在vscode中如果在本地进行了修改,git中会有同步修改
的提示。点击同步按钮,可以将本地修改同步到远程仓库。(同步修改等于先拉取,解决冲突,再推送)
- 分支管理 点击左下角的分支图标,可以查看当前仓库的分支,切换分支等。
- 一般来说单个开发人员也不直接基于dev分支进行开发,而是基于dev分支创建自己的分支,比如feature分支。
- 写完后,在dev分支上进行分支合并feature分支,然后提交dev分支,最后再合并到master分支。