本教程里的git命令例子都是在Git Bash中演示的,会用到一些基本的linux命令,在此为大家提前列举:
ls/ll 查看当前目录
cat 查看文件内容
touch 创建文件
vi vi编辑器(使用vi编辑器是为了方便展示效果,学员可以记事本、editPlus、notPad++等其它编 辑器)
3.1、 Git环境配置
3.1.1 下载与安装
下载地址: https://git-scm.com/download
双击下载的安装文件来安装Git。安装完成后在电脑桌面(也可以是其他目录)点击右键,如果能够看到如下两个菜单则说明Git安装成功。
备注:
Git GUI:Git提供的图形界面工具
Git Bash:Git提供的命令行工具
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息
3.1.2基本配置
- git config --global user.name “yushangxue”<br >git config --global user.email “你的邮箱@qq.com”
复制代码
查看配置信息 - git config --global user.name<br >git config --global user.email
复制代码
3.1.3 常用指令配置别名(可选)
有些常用的指令参数非常多,每次都要输入好多参数,我们可以使用别名。
- 打开用户目录(C:\Users\Administrator),创建 .bashrc 文件
部分windows系统不允许用户创建点号开头的文件,可以打开gitBash,执行 touch ~/.bashrc
- #用于输出git提交日志 <br >alias git-log='git log --pretty=oneline --all --graph --abbrev-commit' <br ><br >#用于输出当前目录所有文件及基本信息 <br >alias ll='ls -al'
复制代码
- 在用户目录 打开gitBash,执行 source ~/.bashrc
3.2、获取本地仓库
要使用Git对我们的代码进行版本控制,首先需要获得本地仓库
1)在电脑的任意位置创建一个空目录(例如test)作为我们的本地Git仓库
2)进入这个目录中,点击右键打开Git bash窗口
3)执行命令git init
4)如果创建成功后可在文件夹下看到隐藏的.git目录。
3.3、基础操作指令
Git工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行Git 的命令而发生变化。
本章节主要讲解如何使用命令来控制这些状态之间的转换:
- git add (工作区 --> 暂存区)
- git commit (暂存区 --> 本地仓库)
提出疑问?暂存区是干什么的?
在软件开发中,很多时候要求我们停止手头上的活去处理别的事情,但此时代码写到一半,无法commit到分支/主干。此时,Git提供了一个暂时存储的功能,将代码add到暂存区,然后将其放在安全的位置,等到紧急任务处理完毕之后,在切回来处理手头上的工作。
3.3.0 工作区与暂存区
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
先来看名词解释。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的gitdemo文件夹就是一个工作区:
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
分支和HEAD的概念我们以后再讲。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:- Git is a distributed version control system.<br >Git is free software distributed under the GPL.<br >Git has a mutable index called stage.
复制代码 然后,在工作区新增一个LICENSE文本文件(内容随便写)。
先用git status查看一下状态:- $ git status<br >On branch master<br >Changes not staged for commit:<br > (use "git add <file>..." to update what will be committed)<br > (use "git checkout -- <file>..." to discard changes in working directory)<br ><br > modified: readme.txt<br ><br >Untracked files:<br > (use "git add <file>..." to include in what will be committed)<br ><br > LICENSE<br ><br >no changes added to commit (use "git add" and/or "git commit -a")
复制代码 Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked。
现在,使用两次命令git add,把readme.txt和LICENSE都添加后,用git status再查看一下:- $ git status<br >On branch master<br >Changes to be committed:<br > (use "git reset HEAD <file>..." to unstage)<br ><br > new file: LICENSE<br > modified: readme.txt
复制代码 现在,暂存区的状态就变成这样了:
所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。- $ git commit -m "understand how stage works"<br >[master e43a48b] understand how stage works<br > 2 files changed, 2 insertions(+)<br > create mode 100644 LICENSE
复制代码 一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:- $ git status<br >On branch master<br >nothing to commit, working tree clean
复制代码 现在版本库变成了这样,暂存区就没有任何内容了:
3.3.1、查看修改的状态(status)
作用:查看的修改的状态(暂存区、工作区)
命令形式:git status
3.3.2、添加工作区到暂存区(add)
作用:添加工作区一个或多个文件的修改到暂存区
命令形式:git add 单个文件名|通配符
将所有修改加入暂存区:git add .
3.3.3、提交暂存区到本地仓库(commit)
作用:提交暂存区内容到本地仓库的当前分支
命令形式:git commit -m '注释内容'
3.3.4、查看提交日志(log)
在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。
最有意思的是 format ,可以定制记录的显示格式。 这样的输出对后期提取分析格外有用——因为你知道输出的格式不会随着 Git 的更新而发生改变:- $ git log --pretty=format:"%h - %an, %ar : %s"<br >ca82a6d - Scott Chacon, 6 years ago : changed the version number<br >085bb3b - Scott Chacon, 6 years ago : removed unnecessary test<br >a11bef0 - Scott Chacon, 6 years ago : first commit
复制代码 git log --pretty=format 常用的选项 列出了 format 接受的常用格式占位符的写法及其代表的意义。
选项说明%H提交的完整哈希值%h提交的简写哈希值%T树的完整哈希值%t树的简写哈希值%P父提交的完整哈希值%p父提交的简写哈希值%an作者名字%ae作者的电子邮件地址%ad作者修订日期(可以用 --date=选项 来定制格式)%ar作者修订日期,按多久以前的方式显示%cn提交者的名字%ce提交者的电子邮件地址%cd提交日期%cr提交日期(距今多长时间)%s提交说明你一定奇怪 作者 和 提交者 之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。 我们会在 分布式 Git 再详细介绍两者之间的细微差别。
当 oneline 或 format 与另一个 log 选项 --graph 结合使用时尤其有用。 这个选项添加了一些 ASCII 字符串来形象地展示你的分支、合并历史:- $ git log --pretty=format:"%h %s" --graph<br >* 2d3acf9 ignore errors from SIGCHLD on trap<br >* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit<br >|\<br >| * 420eac9 Added a method for getting the current branch.<br >* | 30e367c timeout code and tests<br >* | 5a09431 add timeout protection to grit<br >* | e1193f8 support for heads with slashes in them<br >|/<br >* d6016bc require time for xmlschema<br >* 11d191e Merge branch 'defunkt' into local
复制代码 这种输出类型会在我们下一章学完分支与合并以后变得更加有趣。
以上只是简单介绍了一些 git log 命令支持的选项。 git log 的常用选项 列出了我们目前涉及到的和没涉及到的选项,以及它们是如何影响 log 命令的输出的:
选项说明-p按补丁格式显示每个提交引入的差异。--stat显示每次提交的文件修改统计信息。--shortstat只显示 --stat 中最后的行数修改添加移除统计。--name-only仅在提交信息后显示已修改的文件清单。--name-status显示新增、修改、删除的文件清单。--abbrev-commit仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。--relative-date使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。--graph在日志旁以 ASCII 图形显示分支与合并历史。--pretty使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。--oneline--pretty=oneline --abbrev-commit 合用的简写。--decorate标记会让git log显示每个commit的引用(苹果电脑可能会用到)GIT 日志图形化解释
符号解释:
// *表示一个commit, 表示提交是发生在那个分支上的|表示分支前进/表示分叉\表示合入
过程解释:
- base master: master first commit
- |/这个符号表示新分支, 可以看见是新增br1: br1-first-commit
- master前进:master-second-commit
- master merged into br1
- master前进:master-third-commit
- br2前进:br2-first-commit(rebase)
- br2前进:br2-second-commit(rebase【此commit在rebase后提交】)
3.3.5、版本回退/版本穿梭
文件回退
- ## 删除文件(如果没有commit的话,是可以回退回来的,因为当前文件并未从本地版本库移除)<br >git rm 文件名<br ><br >## 文件恢复<br >git checkout head 文件名
复制代码 仓库版本回退
作用:版本切换
命令形式:git reset --hard commitID(版本id)
commitID 可以使用 git-log 或 git log 指令查看
git reflog- # 可以找回被删除的历史提交记录<br >$ git reflog<br ><br >8537950 (HEAD -> master) HEAD@{0}: reset: moving to 8537950<br >bc94e9c HEAD@{1}: reset: moving to bc94e9c<br >8537950 (HEAD -> master) HEAD@{2}: commit: 5.txt 被删除<br >bc94e9c HEAD@{3}: reset: moving to bc94e9c<br >38ca380 HEAD@{4}: commit: 删除1.txt<br >bc94e9c HEAD@{5}: commit: 第二次提交<br >d126f4f HEAD@{6}: commit (initial): 提交第一文件1.txt<br ><br ><br ><br ><br >renwoxing@DESKTOP-9D3GBO0 MINGW64 ~/Desktop/gitdemo (master)<br >$ git-log<br >* 8537950 (HEAD -> master) 5.txt 被删除<br >* bc94e9c 第二次提交<br >* d126f4f 提交第一文件1.txt<br ><br >
复制代码
3.3.6、添加文件至忽略列表
一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动
生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录
中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。下面是一个示例(.net 常用的):
.Net 忽略文件
- # Build and Object Folders<br >bin/<br >obj/<br ># Nuget packages directory<br >packages/<br >## Ignore Visual Studio temporary files, build results, and<br >## files generated by popular Visual Studio add-ons.<br ># User-specific files<br >*.suo<br >*.user<br >*.sln.docstates<br ><br ># Build results<br ><br >[Dd]ebug/<br >[Rr]elease/<br >x64/<br >*_i.c<br >*_p.c<br >*.ilk<br >*.meta<br >*.obj<br >*.pch<br >*.pdb<br >*.pgc<br >*.pgd<br >*.rsp<br >*.sbr<br >*.tlb<br >*.tli<br >*.tlh<br >*.tmp<br >*.log<br >*.vspscc<br >*.vssscc<br >.builds<br ><br ># Visual C++ cache files<br >ipch/<br >*.aps<br >*.ncb<br >*.opensdf<br >*.sdf<br > <br ># Visual Studio profiler<br >*.psess<br >*.vsp<br >*.vspx<br ><br ># Guidance Automation Toolkit<br >*.gpState<br ><br ># ReSharper is a .NET coding add-in<br >_ReSharper*<br ><br ># NCrunch<br >*.ncrunch*<br >.*crunch*.local.xml<br ><br ># Installshield output folder<br >[Ee]xpress<br ><br > <br ><br ># DocProject is a documentation generator add-in<br >DocProject/buildhelp/<br >DocProject/Help<br >UpgradeLog*.XML<br > <br ><br ># Lightswitch<br >_Pvt_Extensions<br >GeneratedArtifacts<br >*.xap<br >ModelManifest.xml<br ><br ># Backup file<br >*.bak<br >*.dll
复制代码 Java 忽略文件
- # eclipse<br >*.pydevproject<br >.project<br >.metadata<br >bin/**<br >tmp/**<br >tmp/**/*<br >*.tmp<br >*.swp<br >*~.nib<br >local.properties<br >.classpath<br >.settings/<br >.loadpath<br ># External tool builders<br >.externalToolBuilders/<br ># Locally stored "Eclipse launch configurations"<br >*.launch<br ># CDT-specific<br >.cproject<br ># PDT-specific<br >.buildpath<br >.factorypath<br ><br ><br >### IntelliJ IDEA ###<br >*.iml<br >*.ipr<br >*.iws<br >.idea<br ><br ><br >### STS ###<br >.apt_generated<br >.classpath<br >.factorypath<br >.project<br >.settings<br >.springBeans<br ><br ><br >### NetBeans ###<br >nbproject/private/<br >build/<br >nbbuild/<br >dist/<br >nbdist/<br >.nb-gradle/<br ><br ><br ># java<br >*.class<br ># Package Files #<br >*.war<br >*.ear<br ><br ><br >#maven<br >target/<br ><br ><br >#gradle<br >.gradle<br >build/<br >gradle/<br >out/<br >!gradle/wrapper/gradle-wrapper.jar<br >.DS_Store<br >.log<br ><br >#rebel<br >rebel.xml<br >log/<br >*.log
复制代码
练习:基础操作
- #####################仓库初始化###################### <br ><br ># 创建目录(git_test01)并在目录下打开gitbash <br ><br >略<br ><br ># 初始化git仓库 <br ><br >git init <br ><br >#####################创建文件并提交##################### <br ><br ># 目录下创建文件 file01.txt <br ><br >touch ./file01.txt<br ><br ># 将修改加入暂存区 <br ><br >git add . <br ><br ># 将修改提交到本地仓库,提交记录内容为:commit 001 <br ><br >git commit -m 'commit 001' <br ><br ># 查看日志 <br ><br >git log <br ><br >####################修改文件并提交###################### <br ><br ># 修改file01的内容为:count=1 <br ><br >略<br ><br ># 将修改加入暂存区 <br ><br >git add . <br ><br ># # 将修改提交到本地仓库,提交记录内容为:update file01 <br ><br >git commit --m 'update file01' <br ><br ># 查看日志 <br ><br >git log <br ><br ># 以精简的方式显示提交记录 <br ><br >git-log <br ><br >####################将最后一次修改还原################## <br ><br ># 查看提交记录 <br ><br >git-log <br ><br ># 找到倒数第2次提交的commitID <br ><br >略<br ><br ># 版本回退 <br >git reset commitID --hard
复制代码
3.4、分支
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离
开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
3.4.1、查看本地分支
命令:git branch
3.4.2、创建本地分支
命令:git branch 分支名
3.4.4、切换分支(checkout)
命令:git checkout 分支名
我们还可以直接切换到一个不存在的分支(创建并切换)
命令:git checkout -b 分支名
3.4.5、合并分支(merge)
一个分支上的提交可以合并到另一个分支
命令:git merge 分支名称
合并分支前,dev分支与master分支目录情况:
合并两个分支后的目录情况:
再比如说:当前分支是A,执行命令:git merge B,意思就是将B分支上的代码合并至当前分支A。
3.4.6 删除分支
不能删除当前分支,只能删除其他分支
git branch -d b1 删除分支时,需要做各种检查
git branch -D b1 不做任何检查,强制删除 (\慎用)
3.4.7、解决冲突 (难点)
当两个分支上对文件的修改可能会存在冲突(conflict),例如同时修改了同一个文件的同一行,当合并分支后必然出现冲突,这时就需要手动解决冲突,解决冲突步骤如下:
- 处理文件中冲突的地方 (需要开发者人为手动的解决)
- 将解决完冲突的文件加入暂存区(add)
- 提交到仓库(commit)
冲突部分的内容处理如下所示
此时就需要与其他开发者沟通,确认使用哪位开发者修改的内容,确认之后,删除冲突部分内容,重新提交
3.4.8 合并提交
在实际开发中,可能一个功能有会N次提交记录,甚至有时候给每次提交取名称都变成一件脑壳疼的问题,并且这种“重复性”的提交如果大家都推送至远端仓库,会导致远端仓库的提交记录密密麻麻,不易梳理。其实我们可以把这些“重复性”的提交合并为一次提交记录再推送至远端仓库。
语法:git rebase -i HEAD~最近几次提交次数
例如, 表示合并最近3次的提交记录:
Git rebase -i HEAD~-3
执行这个命令后会跳到一个vi编辑器
里面的提示有:
pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)
保存之后出现下面的内容改成你想提交的概述即可:
[detached HEAD 8c0b26b] 合并了3次提交
Date: Mon May 9 11:22:01 2022 +0800
1 file changed, 3 insertions(+)
Successfully rebased and updated refs/heads/dev.
保存之后,我们发现提交记录已经被合并了
冲突解决
在 git rebase 过程中,可能会存在冲突,此时就需要解决冲突。
错误提示信息:git rebase -i resumeerror: could not apply ...。- # 查看冲突<br >$ git status<br ><br ># 解决冲突之后,本地提交<br >$ git add .<br ><br ># rebase 继续<br >$ git rebase --continue
复制代码
3.4.9、开发中分支使用原则与流程
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离
开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
在开发中,一般有如下分支使用原则与流程:
master(生产) 分支
线上分支,主分支,中小规模项目作为线上运行的应用对应的分支;
develop(开发)分支
是从master创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线
要求,都可以在此版本进行开发,阶段开发完成后,需要是合并到master分支,准备上线。
feature/xxxx 分支
从develop创建的分支,一般是同期并行开发,但不同期上线时创建的分支,分支上的研发任务完成后合并到develop分支。
hotfix/xxxx分支
从master派生的分支,一般作为线上bug修复使用,修复完成后需要合并到master、test、
develop分支。
还有一些其他分支,在此不再详述,例如test分支(用于代码测试)、pre分支(预上线分支)等等。
3.4.10练习:分支操作
- ###########################创建并切换到dev01分支,在dev01分支提交 <br><br># [master]创建分支dev01 <br><br>git branch dev01 <br><br># [master]切换到dev01 <br><br>git checkout dev01 <br><br># [dev01]创建文件file02.txt <br><br>略<br><br># [dev01]将修改加入暂存区并提交到仓库,提交记录内容为:add file02 on dev <br><br>git add . <br><br>git commit -m 'add file02 on dev' <br><br># [dev01]以精简的方式显示提交记录 <br><br>git-log <br><br>###########################切换到master分支,将dev01合并到master分支 <br><br># [dev01]切换到master分支 <br><br>git checkout master <br><br># [master]合并dev01到master分支 <br><br>git merge dev01 <br><br># [master]以精简的方式显示提交记录 <br><br>git-log <br><br># [master]查看文件变化(目录下也出现了file02.txt) <br><br>略<br><br>##########################删除dev01分支 <br><br># [master]删除dev01分支 <br><br>git branch -d dev01 <br><br># [master]以精简的方式显示提交记录 <br><br>git-log
复制代码
本教程里的git命令例子都是在Git Bash中演示的,会用到一些基本的linux命令,在此为大家提前列举:
ls/ll 查看当前目录
cat 查看文件内容
touch 创建文件
vi vi编辑器(使用vi编辑器是为了方便展示效果,学员可以记事本、editPlus、notPad++等其它编 辑器)
3.1、 Git环境配置
3.1.1 下载与安装
下载地址: https://git-scm.com/download
<img alt="img" >
双击下载的安装文件来安装Git。安装完成后在电脑桌面(也可以是其他目录)点击右键,如果能够看到如下两个菜单则说明Git安装成功。
<img alt="img" >
备注:
Git GUI:Git提供的图形界面工具
Git Bash:Git提供的命令行工具
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息
3.1.2基本配置
- git config --global user.name “yushangxue”<br >git config --global user.email “你的邮箱@qq.com”
复制代码 查看配置信息 - git config --global user.name<br >git config --global user.email
复制代码
<img alt="img" >
3.1.3 常用指令配置别名(可选)
有些常用的指令参数非常多,每次都要输入好多参数,我们可以使用别名。
- 打开用户目录(C:\Users\Administrator),创建 .bashrc 文件
部分windows系统不允许用户创建点号开头的文件,可以打开gitBash,执行 touch ~/.bashrc
- #用于输出git提交日志 <br >alias git-log='git log --pretty=oneline --all --graph --abbrev-commit' <br ><br >#用于输出当前目录所有文件及基本信息 <br >alias ll='ls -al'
复制代码
- 在用户目录 打开gitBash,执行 source ~/.bashrc
<img alt="img" >
3.2、获取本地仓库
要使用Git对我们的代码进行版本控制,首先需要获得本地仓库
1)在电脑的任意位置创建一个空目录(例如test)作为我们的本地Git仓库
2)进入这个目录中,点击右键打开Git bash窗口
3)执行命令git init
4)如果创建成功后可在文件夹下看到隐藏的.git目录。
<img alt="img" >
3.3、基础操作指令
Git工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行Git 的命令而发生变化。
<img alt="img" >
本章节主要讲解如何使用命令来控制这些状态之间的转换:
- git add (工作区 --> 暂存区)
- git commit (暂存区 --> 本地仓库)
提出疑问?暂存区是干什么的?
在软件开发中,很多时候要求我们停止手头上的活去处理别的事情,但此时代码写到一半,无法commit到分支/主干。此时,Git提供了一个暂时存储的功能,将代码add到暂存区,然后将其放在安全的位置,等到紧急任务处理完毕之后,在切回来处理手头上的工作。
3.3.0 工作区与暂存区
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
先来看名词解释。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的gitdemo文件夹就是一个工作区:
<img alt="image-20231031211926244" >
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
<img alt="git-repo" >
分支和HEAD的概念我们以后再讲。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:- Git is a distributed version control system.<br >Git is free software distributed under the GPL.<br >Git has a mutable index called stage.
复制代码 然后,在工作区新增一个LICENSE文本文件(内容随便写)。
先用git status查看一下状态:- $ git status<br >On branch master<br >Changes not staged for commit:<br > (use "git add <file>..." to update what will be committed)<br > (use "git checkout -- <file>..." to discard changes in working directory)<br ><br > modified: readme.txt<br ><br >Untracked files:<br > (use "git add <file>..." to include in what will be committed)<br ><br > LICENSE<br ><br >no changes added to commit (use "git add" and/or "git commit -a")
复制代码 Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked。
现在,使用两次命令git add,把readme.txt和LICENSE都添加后,用git status再查看一下:- $ git status<br >On branch master<br >Changes to be committed:<br > (use "git reset HEAD <file>..." to unstage)<br ><br > new file: LICENSE<br > modified: readme.txt
复制代码 现在,暂存区的状态就变成这样了:
<img alt="git-stage" >
所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。- $ git commit -m "understand how stage works"<br >[master e43a48b] understand how stage works<br > 2 files changed, 2 insertions(+)<br > create mode 100644 LICENSE
复制代码 一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:- $ git status<br >On branch master<br >nothing to commit, working tree clean
复制代码 现在版本库变成了这样,暂存区就没有任何内容了:
<img alt="git-stage-after-commit" >
3.3.1、查看修改的状态(status)
作用:查看的修改的状态(暂存区、工作区)
命令形式:git status
3.3.2、添加工作区到暂存区(add)
作用:添加工作区一个或多个文件的修改到暂存区
命令形式:git add 单个文件名|通配符
将所有修改加入暂存区:git add .
3.3.3、提交暂存区到本地仓库(commit)
作用:提交暂存区内容到本地仓库的当前分支
命令形式:git commit -m '注释内容'
<img alt="img" >
3.3.4、查看提交日志(log)
在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。
最有意思的是 format ,可以定制记录的显示格式。 这样的输出对后期提取分析格外有用——因为你知道输出的格式不会随着 Git 的更新而发生改变:- $ git log --pretty=format:"%h - %an, %ar : %s"<br >ca82a6d - Scott Chacon, 6 years ago : changed the version number<br >085bb3b - Scott Chacon, 6 years ago : removed unnecessary test<br >a11bef0 - Scott Chacon, 6 years ago : first commit
复制代码 git log --pretty=format 常用的选项 列出了 format 接受的常用格式占位符的写法及其代表的意义。
选项说明%H提交的完整哈希值%h提交的简写哈希值%T树的完整哈希值%t树的简写哈希值%P父提交的完整哈希值%p父提交的简写哈希值%an作者名字%ae作者的电子邮件地址%ad作者修订日期(可以用 --date=选项 来定制格式)%ar作者修订日期,按多久以前的方式显示%cn提交者的名字%ce提交者的电子邮件地址%cd提交日期%cr提交日期(距今多长时间)%s提交说明你一定奇怪 作者 和 提交者 之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。 我们会在 分布式 Git 再详细介绍两者之间的细微差别。
当 oneline 或 format 与另一个 log 选项 --graph 结合使用时尤其有用。 这个选项添加了一些 ASCII 字符串来形象地展示你的分支、合并历史:- $ git log --pretty=format:"%h %s" --graph<br >* 2d3acf9 ignore errors from SIGCHLD on trap<br >* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit<br >|\<br >| * 420eac9 Added a method for getting the current branch.<br >* | 30e367c timeout code and tests<br >* | 5a09431 add timeout protection to grit<br >* | e1193f8 support for heads with slashes in them<br >|/<br >* d6016bc require time for xmlschema<br >* 11d191e Merge branch 'defunkt' into local
复制代码 这种输出类型会在我们下一章学完分支与合并以后变得更加有趣。
以上只是简单介绍了一些 git log 命令支持的选项。 git log 的常用选项 列出了我们目前涉及到的和没涉及到的选项,以及它们是如何影响 log 命令的输出的:
选项说明-p按补丁格式显示每个提交引入的差异。--stat显示每次提交的文件修改统计信息。--shortstat只显示 --stat 中最后的行数修改添加移除统计。--name-only仅在提交信息后显示已修改的文件清单。--name-status显示新增、修改、删除的文件清单。--abbrev-commit仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。--relative-date使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。--graph在日志旁以 ASCII 图形显示分支与合并历史。--pretty使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。--oneline--pretty=oneline --abbrev-commit 合用的简写。--decorate标记会让git log显示每个commit的引用(苹果电脑可能会用到)GIT 日志图形化解释
<img alt="image-20231031234915581" >
符号解释:
// *表示一个commit, 表示提交是发生在那个分支上的|表示分支前进/表示分叉\表示合入
过程解释:
- base master: master first commit
- |/这个符号表示新分支, 可以看见是新增br1: br1-first-commit
- master前进:master-second-commit
- master merged into br1
- master前进:master-third-commit
- br2前进:br2-first-commit(rebase)
- br2前进:br2-second-commit(rebase【此commit在rebase后提交】)
3.3.5、版本回退/版本穿梭
文件回退
- ## 删除文件(如果没有commit的话,是可以回退回来的,因为当前文件并未从本地版本库移除)<br >git rm 文件名<br ><br >## 文件恢复<br >git checkout head 文件名
复制代码 仓库版本回退
作用:版本切换
命令形式:git reset --hard commitID(版本id)
commitID 可以使用 git-log 或 git log 指令查看
<img alt="img" >
git reflog- # 可以找回被删除的历史提交记录<br >$ git reflog<br ><br >8537950 (HEAD -> master) HEAD@{0}: reset: moving to 8537950<br >bc94e9c HEAD@{1}: reset: moving to bc94e9c<br >8537950 (HEAD -> master) HEAD@{2}: commit: 5.txt 被删除<br >bc94e9c HEAD@{3}: reset: moving to bc94e9c<br >38ca380 HEAD@{4}: commit: 删除1.txt<br >bc94e9c HEAD@{5}: commit: 第二次提交<br >d126f4f HEAD@{6}: commit (initial): 提交第一文件1.txt<br ><br ><br ><br ><br >renwoxing@DESKTOP-9D3GBO0 MINGW64 ~/Desktop/gitdemo (master)<br >$ git-log<br >* 8537950 (HEAD -> master) 5.txt 被删除<br >* bc94e9c 第二次提交<br >* d126f4f 提交第一文件1.txt<br ><br >
复制代码
3.3.6、添加文件至忽略列表
一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动
生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录
中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。下面是一个示例(.net 常用的):
.Net 忽略文件
- # Build and Object Folders<br >bin/<br >obj/<br ># Nuget packages directory<br >packages/<br >## Ignore Visual Studio temporary files, build results, and<br >## files generated by popular Visual Studio add-ons.<br ># User-specific files<br >*.suo<br >*.user<br >*.sln.docstates<br ><br ># Build results<br ><br >[Dd]ebug/<br >[Rr]elease/<br >x64/<br >*_i.c<br >*_p.c<br >*.ilk<br >*.meta<br >*.obj<br >*.pch<br >*.pdb<br >*.pgc<br >*.pgd<br >*.rsp<br >*.sbr<br >*.tlb<br >*.tli<br >*.tlh<br >*.tmp<br >*.log<br >*.vspscc<br >*.vssscc<br >.builds<br ><br ># Visual C++ cache files<br >ipch/<br >*.aps<br >*.ncb<br >*.opensdf<br >*.sdf<br > <br ># Visual Studio profiler<br >*.psess<br >*.vsp<br >*.vspx<br ><br ># Guidance Automation Toolkit<br >*.gpState<br ><br ># ReSharper is a .NET coding add-in<br >_ReSharper*<br ><br ># NCrunch<br >*.ncrunch*<br >.*crunch*.local.xml<br ><br ># Installshield output folder<br >[Ee]xpress<br ><br > <br ><br ># DocProject is a documentation generator add-in<br >DocProject/buildhelp/<br >DocProject/Help<br >UpgradeLog*.XML<br > <br ><br ># Lightswitch<br >_Pvt_Extensions<br >GeneratedArtifacts<br >*.xap<br >ModelManifest.xml<br ><br ># Backup file<br >*.bak<br >*.dll
复制代码 Java 忽略文件
- # eclipse<br >*.pydevproject<br >.project<br >.metadata<br >bin/**<br >tmp/**<br >tmp/**/*<br >*.tmp<br >*.swp<br >*~.nib<br >local.properties<br >.classpath<br >.settings/<br >.loadpath<br ># External tool builders<br >.externalToolBuilders/<br ># Locally stored "Eclipse launch configurations"<br >*.launch<br ># CDT-specific<br >.cproject<br ># PDT-specific<br >.buildpath<br >.factorypath<br ><br ><br >### IntelliJ IDEA ###<br >*.iml<br >*.ipr<br >*.iws<br >.idea<br ><br ><br >### STS ###<br >.apt_generated<br >.classpath<br >.factorypath<br >.project<br >.settings<br >.springBeans<br ><br ><br >### NetBeans ###<br >nbproject/private/<br >build/<br >nbbuild/<br >dist/<br >nbdist/<br >.nb-gradle/<br ><br ><br ># java<br >*.class<br ># Package Files #<br >*.war<br >*.ear<br ><br ><br >#maven<br >target/<br ><br ><br >#gradle<br >.gradle<br >build/<br >gradle/<br >out/<br >!gradle/wrapper/gradle-wrapper.jar<br >.DS_Store<br >.log<br ><br >#rebel<br >rebel.xml<br >log/<br >*.log
复制代码
练习:基础操作
- #####################仓库初始化###################### <br ><br ># 创建目录(git_test01)并在目录下打开gitbash <br ><br >略<br ><br ># 初始化git仓库 <br ><br >git init <br ><br >#####################创建文件并提交##################### <br ><br ># 目录下创建文件 file01.txt <br ><br >touch ./file01.txt<br ><br ># 将修改加入暂存区 <br ><br >git add . <br ><br ># 将修改提交到本地仓库,提交记录内容为:commit 001 <br ><br >git commit -m 'commit 001' <br ><br ># 查看日志 <br ><br >git log <br ><br >####################修改文件并提交###################### <br ><br ># 修改file01的内容为:count=1 <br ><br >略<br ><br ># 将修改加入暂存区 <br ><br >git add . <br ><br ># # 将修改提交到本地仓库,提交记录内容为:update file01 <br ><br >git commit --m 'update file01' <br ><br ># 查看日志 <br ><br >git log <br ><br ># 以精简的方式显示提交记录 <br ><br >git-log <br ><br >####################将最后一次修改还原################## <br ><br ># 查看提交记录 <br ><br >git-log <br ><br ># 找到倒数第2次提交的commitID <br ><br >略<br ><br ># 版本回退 <br >git reset commitID --hard
复制代码
3.4、分支
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离
开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
3.4.1、查看本地分支
命令:git branch
<img alt="img" >
3.4.2、创建本地分支
命令:git branch 分支名
<img alt="img" >
3.4.4、切换分支(checkout)
命令:git checkout 分支名
<img alt="img" >
我们还可以直接切换到一个不存在的分支(创建并切换)
命令:git checkout -b 分支名
<img alt="img" >
3.4.5、合并分支(merge)
一个分支上的提交可以合并到另一个分支
命令:git merge 分支名称
合并分支前,dev分支与master分支目录情况:
<img alt="img" >
<img alt="img" >
合并两个分支后的目录情况:
<img alt="img" >
再比如说:当前分支是A,执行命令:git merge B,意思就是将B分支上的代码合并至当前分支A。
3.4.6 删除分支
不能删除当前分支,只能删除其他分支
git branch -d b1 删除分支时,需要做各种检查
<img alt="img" >
git branch -D b1 不做任何检查,强制删除 (\慎用)
3.4.7、解决冲突 (难点)
当两个分支上对文件的修改可能会存在冲突(conflict),例如同时修改了同一个文件的同一行,当合并分支后必然出现冲突,这时就需要手动解决冲突,解决冲突步骤如下:
<img alt="img" >
- 处理文件中冲突的地方 (需要开发者人为手动的解决)
- 将解决完冲突的文件加入暂存区(add)
- 提交到仓库(commit)
冲突部分的内容处理如下所示
<img alt="img" >
此时就需要与其他开发者沟通,确认使用哪位开发者修改的内容,确认之后,删除冲突部分内容,重新提交
<img alt="img" >
<img alt="img" >
3.4.8 合并提交
在实际开发中,可能一个功能有会N次提交记录,甚至有时候给每次提交取名称都变成一件脑壳疼的问题,并且这种“重复性”的提交如果大家都推送至远端仓库,会导致远端仓库的提交记录密密麻麻,不易梳理。其实我们可以把这些“重复性”的提交合并为一次提交记录再推送至远端仓库。
语法:git rebase -i HEAD~最近几次提交次数
例如, 表示合并最近3次的提交记录:
Git rebase -i HEAD~-3
<img alt="img" >
执行这个命令后会跳到一个vi编辑器
<img alt="img" >
里面的提示有:
pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)
保存之后出现下面的内容改成你想提交的概述即可:
<img alt="img" >
[detached HEAD 8c0b26b] 合并了3次提交
Date: Mon May 9 11:22:01 2022 +0800
1 file changed, 3 insertions(+)
Successfully rebased and updated refs/heads/dev.
保存之后,我们发现提交记录已经被合并了
<img alt="img" >
冲突解决
在 git rebase 过程中,可能会存在冲突,此时就需要解决冲突。
错误提示信息:git rebase -i resumeerror: could not apply ...。- # 查看冲突<br >$ git status<br ><br ># 解决冲突之后,本地提交<br >$ git add .<br ><br ># rebase 继续<br >$ git rebase --continue
复制代码
3.4.9、开发中分支使用原则与流程
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离
开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
在开发中,一般有如下分支使用原则与流程:
master(生产) 分支
线上分支,主分支,中小规模项目作为线上运行的应用对应的分支;
develop(开发)分支
是从master创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线
要求,都可以在此版本进行开发,阶段开发完成后,需要是合并到master分支,准备上线。
feature/xxxx 分支
从develop创建的分支,一般是同期并行开发,但不同期上线时创建的分支,分支上的研发任务完成后合并到develop分支。
hotfix/xxxx分支
从master派生的分支,一般作为线上bug修复使用,修复完成后需要合并到master、test、
develop分支。
还有一些其他分支,在此不再详述,例如test分支(用于代码测试)、pre分支(预上线分支)等等。
3.4.10练习:分支操作
- ###########################创建并切换到dev01分支,在dev01分支提交 <br><br># [master]创建分支dev01 <br><br>git branch dev01 <br><br># [master]切换到dev01 <br><br>git checkout dev01 <br><br># [dev01]创建文件file02.txt <br><br>略<br><br># [dev01]将修改加入暂存区并提交到仓库,提交记录内容为:add file02 on dev <br><br>git add . <br><br>git commit -m 'add file02 on dev' <br><br># [dev01]以精简的方式显示提交记录 <br><br>git-log <br><br>###########################切换到master分支,将dev01合并到master分支 <br><br># [dev01]切换到master分支 <br><br>git checkout master <br><br># [master]合并dev01到master分支 <br><br>git merge dev01 <br><br># [master]以精简的方式显示提交记录 <br><br>git-log <br><br># [master]查看文件变化(目录下也出现了file02.txt) <br><br>略<br><br>##########################删除dev01分支 <br><br># [master]删除dev01分支 <br><br>git branch -d dev01 <br><br># [master]以精简的方式显示提交记录 <br><br>git-log
复制代码
来源:https://www.cnblogs.com/xuyubing/p/17991092
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |