3、Git安装与常用命令

本教程里的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基本配置

  1. 打开Git Bash

  2. 设置用户信息

  

git config --global user.name “yushangxue”
git config --global user.email “你的邮箱@qq.com”

 

查看配置信息

git config --global user.name
git config --global user.email

 

 

3.1.3 常用指令配置别名(可选)

有些常用的指令参数非常多,每次都要输入好多参数,我们可以使用别名。

  1. 打开用户目录(C:\Users\Administrator),创建 .bashrc 文件

部分windows系统不允许用户创建点号开头的文件,可以打开gitBash,执行 touch ~/.bashrc

  1. 在 .bashrc 文件中输入如下内容:

#用于输出git提交日志 
alias git-log='git log --pretty=oneline --all --graph --abbrev-commit'

#用于输出当前目录所有文件及基本信息
alias ll='ls -al'

 

  1. 在用户目录 打开gitBash,执行 source ~/.bashrc

 

 

3.2、获取本地仓库

要使用Git对我们的代码进行版本控制,首先需要获得本地仓库

1)在电脑的任意位置创建一个空目录(例如test)作为我们的本地Git仓库

2)进入这个目录中,点击右键打开Git bash窗口

3)执行命令git init

4)如果创建成功后可在文件夹下看到隐藏的.git目录。

 

3.3、基础操作指令

Git工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行Git 的命令而发生变化。

 

 

本章节主要讲解如何使用命令来控制这些状态之间的转换:

  1. git add (工作区 --> 暂存区)

  2. 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.
Git is free software distributed under the GPL.
Git has a mutable index called stage.

然后,在工作区新增一个LICENSE文本文件(内容随便写)。

先用git status查看一下状态:

$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: readme.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)

LICENSE

no changes added to commit (use "git add" and/or "git commit -a")

Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked

现在,使用两次命令git add,把readme.txtLICENSE都添加后,用git status再查看一下:

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file: LICENSE
modified: readme.txt

现在,暂存区的状态就变成这样了:

 

 

所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

$ git commit -m "understand how stage works"
[master e43a48b] understand how stage works
2 files changed, 2 insertions(+)
create mode 100644 LICENSE

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

$ git status
On branch master
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"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
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 再详细介绍两者之间的细微差别。

onelineformat 与另一个 log 选项 --graph 结合使用时尤其有用。 这个选项添加了一些 ASCII 字符串来形象地展示你的分支、合并历史:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
* 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, 表示提交是发生在那个分支上的|表示分支前进/表示分叉\表示合入

过程解释:

  1. base master: master first commit

  2. |/这个符号表示新分支, 可以看见是新增br1: br1-first-commit

  3. master前进:master-second-commit

  4. master merged into br1

  5. master前进:master-third-commit

  6. br2前进:br2-first-commit(rebase)

  7. br2前进:br2-second-commit(rebase【此commit在rebase后提交】)

 

 

3.3.5、版本回退/版本穿梭

文件回退

## 删除文件(如果没有commit的话,是可以回退回来的,因为当前文件并未从本地版本库移除)
git rm 文件名

## 文件恢复
git checkout head 文件名

仓库版本回退

作用:版本切换

命令形式:git reset --hard commitID(版本id)

commitID 可以使用 git-log 或 git log 指令查看

 

 

git reflog

# 可以找回被删除的历史提交记录
$ git reflog

8537950 (HEAD -> master) HEAD@{0}: reset: moving to 8537950
bc94e9c HEAD@{1}: reset: moving to bc94e9c
8537950 (HEAD -> master) HEAD@{2}: commit: 5.txt 被删除
bc94e9c HEAD@{3}: reset: moving to bc94e9c
38ca380 HEAD@{4}: commit: 删除1.txt
bc94e9c HEAD@{5}: commit: 第二次提交
d126f4f HEAD@{6}: commit (initial): 提交第一文件1.txt




renwoxing@DESKTOP-9D3GBO0 MINGW64 ~/Desktop/gitdemo (master)
$ git-log
* 8537950 (HEAD -> master) 5.txt 被删除
* bc94e9c 第二次提交
* d126f4f 提交第一文件1.txt

 

3.3.6、添加文件至忽略列表

一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动

生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录

中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。下面是一个示例(.net 常用的):

.Net 忽略文件

# Build and Object Folders
bin/
obj/
# Nuget packages directory
packages/
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates

# Build results

[Dd]ebug/
[Rr]elease/
x64/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.log
*.vspscc
*.vssscc
.builds

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*

# NCrunch
*.ncrunch*
.*crunch*.local.xml

# Installshield output folder
[Ee]xpress



# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help
UpgradeLog*.XML


# Lightswitch
_Pvt_Extensions
GeneratedArtifacts
*.xap
ModelManifest.xml

# Backup file
*.bak
*.dll

Java 忽略文件

# eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
.factorypath


### IntelliJ IDEA ###
*.iml
*.ipr
*.iws
.idea


### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans


### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/


# java
*.class
# Package Files #
*.war
*.ear


#maven
target/


#gradle
.gradle
build/
gradle/
out/
!gradle/wrapper/gradle-wrapper.jar
.DS_Store
.log

#rebel
rebel.xml
log/
*.log

 

练习:基础操作

#####################仓库初始化###################### 

# 创建目录(git_test01)并在目录下打开gitbash



# 初始化git仓库

git init

#####################创建文件并提交#####################

# 目录下创建文件 file01.txt

touch ./file01.txt

# 将修改加入暂存区

git add .

# 将修改提交到本地仓库,提交记录内容为:commit 001

git commit -m 'commit 001'

# 查看日志

git log

####################修改文件并提交######################

# 修改file01的内容为:count=1



# 将修改加入暂存区

git add .

# # 将修改提交到本地仓库,提交记录内容为:update file01

git commit --m 'update file01'

# 查看日志

git log

# 以精简的方式显示提交记录

git-log

####################将最后一次修改还原##################

# 查看提交记录

git-log

# 找到倒数第2次提交的commitID



# 版本回退
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),例如同时修改了同一个文件的同一行,当合并分支后必然出现冲突,这时就需要手动解决冲突,解决冲突步骤如下:

 

  1. 处理文件中冲突的地方 (需要开发者人为手动的解决)

  2. 将解决完冲突的文件加入暂存区(add)

  3. 提交到仓库(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 ...

# 查看冲突
$ git status

# 解决冲突之后,本地提交
$ git add .

# rebase 继续
$ 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分支提交 

# [master]创建分支dev01

git branch dev01

# [master]切换到dev01

git checkout dev01

# [dev01]创建文件file02.txt



# [dev01]将修改加入暂存区并提交到仓库,提交记录内容为:add file02 on dev

git add .

git commit -m 'add file02 on dev'

# [dev01]以精简的方式显示提交记录

git-log

###########################切换到master分支,将dev01合并到master分支

# [dev01]切换到master分支

git checkout master

# [master]合并dev01到master分支

git merge dev01

# [master]以精简的方式显示提交记录

git-log

# [master]查看文件变化(目录下也出现了file02.txt)



##########################删除dev01分支

# [master]删除dev01分支

git branch -d dev01

# [master]以精简的方式显示提交记录

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

双击下载的安装文件来安装Git。安装完成后在电脑桌面(也可以是其他目录)点击右键,如果能够看到如下两个菜单则说明Git安装成功。

img

备注:

Git GUI:Git提供的图形界面工具

Git Bash:Git提供的命令行工具

当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息

3.1.2基本配置

  1. 打开Git Bash

  2. 设置用户信息

git config --global user.name “yushangxue”
git config --global user.email “你的邮箱@qq.com”

查看配置信息

git config --global user.name
git config --global user.email

 

img

3.1.3 常用指令配置别名(可选)

有些常用的指令参数非常多,每次都要输入好多参数,我们可以使用别名。

  1. 打开用户目录(C:\Users\Administrator),创建 .bashrc 文件

部分windows系统不允许用户创建点号开头的文件,可以打开gitBash,执行 touch ~/.bashrc

  1. 在 .bashrc 文件中输入如下内容:

#用于输出git提交日志 
alias git-log='git log --pretty=oneline --all --graph --abbrev-commit'

#用于输出当前目录所有文件及基本信息
alias ll='ls -al'

 

  1. 在用户目录 打开gitBash,执行 source ~/.bashrc

img

 

3.2、获取本地仓库

要使用Git对我们的代码进行版本控制,首先需要获得本地仓库

1)在电脑的任意位置创建一个空目录(例如test)作为我们的本地Git仓库

2)进入这个目录中,点击右键打开Git bash窗口

3)执行命令git init

4)如果创建成功后可在文件夹下看到隐藏的.git目录。

img

3.3、基础操作指令

Git工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行Git 的命令而发生变化。

 

img

本章节主要讲解如何使用命令来控制这些状态之间的转换:

  1. git add (工作区 --> 暂存区)

  2. git commit (暂存区 --> 本地仓库)

 

提出疑问?暂存区是干什么的?

在软件开发中,很多时候要求我们停止手头上的活去处理别的事情,但此时代码写到一半,无法commit到分支/主干。此时,Git提供了一个暂时存储的功能,将代码add到暂存区,然后将其放在安全的位置,等到紧急任务处理完毕之后,在切回来处理手头上的工作。

 

3.3.0 工作区与暂存区

Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。

先来看名词解释。

工作区(Working Directory)

就是你在电脑里能看到的目录,比如我的gitdemo文件夹就是一个工作区:

image-20231031211926244

 

版本库(Repository)

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

git-repo

分支和HEAD的概念我们以后再讲。

前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.

然后,在工作区新增一个LICENSE文本文件(内容随便写)。

先用git status查看一下状态:

$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: readme.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)

LICENSE

no changes added to commit (use "git add" and/or "git commit -a")

Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked

现在,使用两次命令git add,把readme.txtLICENSE都添加后,用git status再查看一下:

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file: LICENSE
modified: readme.txt

现在,暂存区的状态就变成这样了:

git-stage

所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

$ git commit -m "understand how stage works"
[master e43a48b] understand how stage works
2 files changed, 2 insertions(+)
create mode 100644 LICENSE

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

$ git status
On branch master
nothing to commit, working tree clean

现在版本库变成了这样,暂存区就没有任何内容了:

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

3.3.4、查看提交日志(log)

在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。

最有意思的是 format ,可以定制记录的显示格式。 这样的输出对后期提取分析格外有用——因为你知道输出的格式不会随着 Git 的更新而发生改变:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
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 再详细介绍两者之间的细微差别。

onelineformat 与另一个 log 选项 --graph 结合使用时尤其有用。 这个选项添加了一些 ASCII 字符串来形象地展示你的分支、合并历史:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
* 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 日志图形化解释

image-20231031234915581

符号解释:

// *表示一个commit, 表示提交是发生在那个分支上的|表示分支前进/表示分叉\表示合入

过程解释:

  1. base master: master first commit

  2. |/这个符号表示新分支, 可以看见是新增br1: br1-first-commit

  3. master前进:master-second-commit

  4. master merged into br1

  5. master前进:master-third-commit

  6. br2前进:br2-first-commit(rebase)

  7. br2前进:br2-second-commit(rebase【此commit在rebase后提交】)

 

 

3.3.5、版本回退/版本穿梭

文件回退

## 删除文件(如果没有commit的话,是可以回退回来的,因为当前文件并未从本地版本库移除)
git rm 文件名

## 文件恢复
git checkout head 文件名

仓库版本回退

作用:版本切换

命令形式:git reset --hard commitID(版本id)

commitID 可以使用 git-log 或 git log 指令查看

img

 

git reflog

# 可以找回被删除的历史提交记录
$ git reflog

8537950 (HEAD -> master) HEAD@{0}: reset: moving to 8537950
bc94e9c HEAD@{1}: reset: moving to bc94e9c
8537950 (HEAD -> master) HEAD@{2}: commit: 5.txt 被删除
bc94e9c HEAD@{3}: reset: moving to bc94e9c
38ca380 HEAD@{4}: commit: 删除1.txt
bc94e9c HEAD@{5}: commit: 第二次提交
d126f4f HEAD@{6}: commit (initial): 提交第一文件1.txt




renwoxing@DESKTOP-9D3GBO0 MINGW64 ~/Desktop/gitdemo (master)
$ git-log
* 8537950 (HEAD -> master) 5.txt 被删除
* bc94e9c 第二次提交
* d126f4f 提交第一文件1.txt

 

3.3.6、添加文件至忽略列表

一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动

生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录

中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。下面是一个示例(.net 常用的):

.Net 忽略文件

# Build and Object Folders
bin/
obj/
# Nuget packages directory
packages/
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates

# Build results

[Dd]ebug/
[Rr]elease/
x64/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.log
*.vspscc
*.vssscc
.builds

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*

# NCrunch
*.ncrunch*
.*crunch*.local.xml

# Installshield output folder
[Ee]xpress



# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help
UpgradeLog*.XML


# Lightswitch
_Pvt_Extensions
GeneratedArtifacts
*.xap
ModelManifest.xml

# Backup file
*.bak
*.dll

Java 忽略文件

# eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
.factorypath


### IntelliJ IDEA ###
*.iml
*.ipr
*.iws
.idea


### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans


### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/


# java
*.class
# Package Files #
*.war
*.ear


#maven
target/


#gradle
.gradle
build/
gradle/
out/
!gradle/wrapper/gradle-wrapper.jar
.DS_Store
.log

#rebel
rebel.xml
log/
*.log

 

练习:基础操作

#####################仓库初始化###################### 

# 创建目录(git_test01)并在目录下打开gitbash



# 初始化git仓库

git init

#####################创建文件并提交#####################

# 目录下创建文件 file01.txt

touch ./file01.txt

# 将修改加入暂存区

git add .

# 将修改提交到本地仓库,提交记录内容为:commit 001

git commit -m 'commit 001'

# 查看日志

git log

####################修改文件并提交######################

# 修改file01的内容为:count=1



# 将修改加入暂存区

git add .

# # 将修改提交到本地仓库,提交记录内容为:update file01

git commit --m 'update file01'

# 查看日志

git log

# 以精简的方式显示提交记录

git-log

####################将最后一次修改还原##################

# 查看提交记录

git-log

# 找到倒数第2次提交的commitID



# 版本回退
git reset commitID --hard

 

3.4、分支

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离

开来进行重大的Bug修改、开发新的功能,以免影响开发主线。

3.4.1、查看本地分支

命令:git branch

img

3.4.2、创建本地分支

命令:git branch 分支名

img

3.4.4、切换分支(checkout)

命令:git checkout 分支名

img

我们还可以直接切换到一个不存在的分支(创建并切换)

命令:git checkout -b 分支名

img

3.4.5、合并分支(merge)

一个分支上的提交可以合并到另一个分支

命令:git merge 分支名称

 

合并分支前,dev分支与master分支目录情况:

img

img

合并两个分支后的目录情况:

img

再比如说:当前分支是A,执行命令:git merge B,意思就是将B分支上的代码合并至当前分支A。

 

 

3.4.6 删除分支

不能删除当前分支,只能删除其他分支

git branch -d b1 删除分支时,需要做各种检查

img

git branch -D b1 不做任何检查,强制删除 (\慎用

3.4.7、解决冲突 (难点)

当两个分支上对文件的修改可能会存在冲突(conflict),例如同时修改了同一个文件的同一行,当合并分支后必然出现冲突,这时就需要手动解决冲突,解决冲突步骤如下:

img

  1. 处理文件中冲突的地方 (需要开发者人为手动的解决)

  2. 将解决完冲突的文件加入暂存区(add)

  3. 提交到仓库(commit)

 

冲突部分的内容处理如下所示

img

此时就需要与其他开发者沟通,确认使用哪位开发者修改的内容,确认之后,删除冲突部分内容,重新提交

img

 

img

3.4.8 合并提交

在实际开发中,可能一个功能有会N次提交记录,甚至有时候给每次提交取名称都变成一件脑壳疼的问题,并且这种“重复性”的提交如果大家都推送至远端仓库,会导致远端仓库的提交记录密密麻麻,不易梳理。其实我们可以把这些“重复性”的提交合并为一次提交记录再推送至远端仓库。

语法:git rebase -i HEAD~最近几次提交次数

例如, 表示合并最近3次的提交记录:

Git rebase -i HEAD~-3

img

执行这个命令后会跳到一个vi编辑器

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

[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

冲突解决

git rebase 过程中,可能会存在冲突,此时就需要解决冲突。

错误提示信息:git rebase -i resumeerror: could not apply ...

# 查看冲突
$ git status

# 解决冲突之后,本地提交
$ git add .

# rebase 继续
$ 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分支提交 

# [master]创建分支dev01

git branch dev01

# [master]切换到dev01

git checkout dev01

# [dev01]创建文件file02.txt



# [dev01]将修改加入暂存区并提交到仓库,提交记录内容为:add file02 on dev

git add .

git commit -m 'add file02 on dev'

# [dev01]以精简的方式显示提交记录

git-log

###########################切换到master分支,将dev01合并到master分支

# [dev01]切换到master分支

git checkout master

# [master]合并dev01到master分支

git merge dev01

# [master]以精简的方式显示提交记录

git-log

# [master]查看文件变化(目录下也出现了file02.txt)



##########################删除dev01分支

# [master]删除dev01分支

git branch -d dev01

# [master]以精简的方式显示提交记录

git-log

 

 

 
posted @ 2024-01-27 09:22  誉尚学教育  阅读(99)  评论(0编辑  收藏  举报