Git使用分享
一、Git概述
1.1 Git历史
Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。 到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。
到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本控制系统。
他们对新的系统制订了若干目标:
- 速度
- 简单的设计
- 对非线性开发模式的强力支持(允许成千上万个并行开发的分支)
- 完全分布式
- 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
1.2 Git与SVN对比
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而开发人员工作的时候,用的都是自己的电脑,所以首先要从中央服务器下载最新的版本,然后开发,开发完后,需要把自己开发的代码提交到中央服务器。
Git 与 SVN 区别点:
- 1、Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。
- 2、Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
- 3、Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
- 4、Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
- 5、Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
集中式版本控制工具缺点:
- 服务器单点故障
- 容错性差
Git是分布式版本控制系统(Distributed Version Control System,简称 DVCS) ,分为两种类型的仓库: - 本地仓库:是在开发人员自己电脑上的Git仓库
- 远程仓库:是在远程服务器上的Git仓库
1.3 Git工作流程
工作流程如下:
1.从远程仓库中克隆代码到本地仓库
2.从本地仓库中checkout代码然后进行代码修改
3.在提交前先将代码提交到暂存区
4.提交到本地仓库。本地仓库中保存修改的各个历史版本
5.修改完成后,需要和团队成员共享代码时,将代码push到远程仓库1.4 Git下载与安装
下载地址: https://git-scm.com/download
下载完成后可以得到如下安装文件:
这里默认下载的是64位的软件
双击下载的安装文件来安装Git。
一直下一步直到安装完成即可
安装完成后在电脑桌面(也可以是其他目录)点击右键,如果能够看到如下两个菜单则说明Git安装成功。
Git GUI:Git提供的图形界面工具
Git Bash:Git提供的命令行工具二、Git代码托管服务
2.1 常用的Git代码托管服务
前面我们已经知道了Git中存在两种类型的仓库,即本地仓库和远程仓库。那么我们如何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现,其中比较常用的有GitHub、码云、GitLab等。
- gitHub( 地址:https://github.com/ )是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名gitHub
- 码云(地址: https://gitee.com/ )是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快
- GitLab (地址: https://about.gitlab.com/ )是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务
本次使用码云作为演示,码云在国内用起来网速比GitHub快
2.2 在码云注册账号
要想使用码云的相关服务,需要注册账号(地址: https://gitee.com/signup )
2.3 登录码云并创建Git远程仓库
注册完成后就可以使用刚刚注册的邮箱进行登录(地址: https://gitee.com/login )
登录成功后就可以创建Git远程仓库
创建完成后可以查看仓库信息
每个Git远程仓库都会对应一个网络地址,可以点击克隆/下载按钮弹出窗口并点击复制按钮获得这个网络地址
2.4 邀请其他用户成为仓库成员
前面已经在码云上创建了自己的远程仓库,目前仓库成员只有自己一个人(身份为管理员)。在企业实际开发中,一个项目往往是由多个人共同开发完成的,为了使多个参与者都有权限操作远程仓库,就需要邀请其他项目参与者成为当前仓库的成员。
三、Git常用命令
先学习如下一些命令和概念:
- 环境配置
- 获取Git仓库
- 工作目录、暂存区以及版本库概念
- Git工作目录下文件的两种状态
- 本地仓库操作
- 远程仓库的使用
- 分支
- 标签
3.1 环境配置
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息
设置用户信息git config --global user.name “your name”
git config --global user.email “your name@gmail.com”
查看配置信息git config --list
git config user.name
通过上面的命令设置的信息会保存在~/.gitconfig
文件中
3.2 获取Git仓库
要使用Git对我们的代码进行版本控制,首先需要获得Git仓库
获取Git仓库通常有两种方式:
- 在电脑的任意位置创建一个空目录(例如testGit)作为我们的本地Git仓库
- 进入这个目录中,点击右键打开Git bash窗口
- 执行命令
git init
- 如果在当前目录中看到.git文件夹(此文件夹为隐藏文件夹)则说明Git仓库创建成功
3.2.2 从远程仓库克隆
可以通过Git提供的命令从远程仓库进行克隆,将远程仓库克隆到本地
命令形式为:git clone
远程Git仓库地址
执行如下命令以创建一个本地仓库的克隆版本:
git clone /path/to/repository
如果是远端服务器上的仓库,你的命令会是这个样子:git clone username@host:/path/to/repository
3.3 工作目录、暂存区以及版本库概念
为了更好的学习Git,我们需要了解Git相关的一些概念,这些概念在后面的学习中会经常提到
版本库:前面看到的.git隐藏文件夹就是版本库,版本库中存储了很多配置信息、日志信息和文件版本信息等
工作目录(工作区):包含.git文件夹的目录就是工作目录,主要用于存放开发的代码
暂存区:.git文件夹中有很多文件,其中有一个index文件就是暂存区,也可以叫做stage。暂存区是一个临时保存修改文件的地方
HEAD:指向你最近一次提交后的结果
下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage/index),标记为 “master” 的是 master 分支所代表的目录树。
图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个”游标”。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行
git reset HEAD
命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。当执行
git rm --cached <file>
命令时,会直接从暂存区删除文件,工作区则不做出改变。当执行
git checkout .
或者 git checkout-- <file>
命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。当执行
git checkout HEAD .
或者git checkout HEAD <file>
命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。3.4 Git工作目录下文件的五种状态
Git工作目录下的文件存在五种状态:
untracked 未跟踪(未被纳入版本控制)
tracked 已跟踪(被纳入版本控制)
unmodified 未修改状态
modified 已修改状态
staged 已暂存状态
这些文件的状态会随着我们执行Git的命令发生变化3.5 本地仓库操作
git status 查看文件状态,也可以使用
git status –s
使输出信息更加简洁1
2
3
4
5
6
7
8
9
10
11
12
13
14PS D:\test> git status
On branch master
Your branch is up to date with 'origin/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.md
no changes added to commit (use "git add" and/or "git commit -a")
PS D:\test> git status -s
M README.md
PS D:\test>git add 将未跟踪的文件加入暂存区
将新创建的文件加入暂存区后查看文件状态1
2
3
4
5
6
7
8
9
10
11PS D:\test> git add .\README.md
PS D:\test> git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
PS D:\test>git reset 将暂存区的文件取消暂存
将文件取消暂存后查看文件状态1
2
3
4
5
6
7
8
9
10
11
12
13
14
15PS D:\test> git reset .\README.md
Unstaged changes after reset:
M README.md
PS D:\test> git status
On branch master
Your branch is up to date with 'origin/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.md
no changes added to commit (use "git add" and/or "git commit -a")
PS D:\test>git commit 将暂存区的文件修改提交到本地仓库
1
2
3
4
5
6
7
8
9
10
11PS D:\test> git add .\README.md
PS D:\test> git commit -m "update Readme" .\README.md
[master 7ac056e] update Readme
1 file changed, 4 insertions(+)
PS D:\test> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
PS D:\test>git rm 删除文件
删除文件后查看文件状态1
2
3
4
5
6
7
8
9
10
11
12
13PS D:\test> git rm .\README.md
rm 'README.md'
PS D:\test> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: README.md
PS D:\test>上面删除的只是工作区的文件,需要提交到本地仓库
将文件添加至忽略列表
一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。下面是一个示例:1
2
3
4
5
6
7
8
9
10
11
12# no .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory
doc/**/*.pdf3.6 远程仓库操作
前面执行的命令操作都是针对的本地仓库,本章节我们会学习关于远程仓库的一些操作,具体包括:
查看远程仓库
如果想查看已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出指定的每一个远程服务器的简写。 如果已经克隆了远程仓库,那么至少应该能看到 origin ,这是 Git 克隆的仓库服务器的默认名字1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17PS D:\test> git remote
origin
PS D:\test> git remote -v
origin https://gitee.com/fusionshen/test.git (fetch)
origin https://gitee.com/fusionshen/test.git (push)
PS D:\test> git remote show origin
* remote origin
Fetch URL: https://gitee.com/fusionshen/test.git
Push URL: https://gitee.com/fusionshen/test.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
PS D:\test>添加远程仓库
运行 git remote add < shortname> < url> 添加一个新的远程 Git 仓库,同时指定一个可以引用的简写1
2
3
4
5
6
7
8
9
10
11PS D:\minhang\testGit> git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
PS D:\minhang\testGit> git remote add origin https://gitee.com/fusionshen/test.git
PS D:\minhang\testGit> git remote -v
origin https://gitee.com/fusionshen/test.git (fetch)
origin https://gitee.com/fusionshen/test.git (push)
PS D:\minhang\testGit>从远程仓库克隆
如果你想获得一份已经存在了的 Git 仓库的拷贝,这时就要用到 git clone 命令。 Git 克隆的是该 Git 仓库服务器上的几乎所有数据(包括日志信息、历史记录等),而不仅仅是复制工作所需要的文件。 当你执行 git clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
克隆仓库的命令格式是 git clone [url]移除无效的远程仓库
如果因为一些原因想要移除一个远程仓库 ,可以使用 git remote rm1
2
3
4
5PS D:\minhang\testGit> git remote
origin
PS D:\minhang\testGit> git remote rm origin
PS D:\minhang\testGit> git remote
PS D:\minhang\testGit>注意:此命令只是从本地移除远程仓库的记录,并不会真正影响到远程仓库
从远程仓库中抓取与拉取
git fetch 是从远程仓库获取最新版本到本地仓库,不会自动merge
git pull 是从远程仓库获取最新版本并merge到本地仓库,即git fetch + git merge注意:如果当前本地仓库不是从远程仓库克隆,而是本地创建的仓库,并且仓库中存在文件,此时再从远程仓库拉取文件的时候会报错(fatal: refusing to merge unrelated histories ),解决此问题可以在git pull命令后加入参数–allow-unrelated-histories
当执行git中的“git pull origin master –allow-unrelated-histories”命令时,会出现“ couldn’t find remote ref –allow-unrelated-histories”的错误,
输入如下命令即可解决:
git pull –rebase origin master将本地分支与远程分支关联:
git branch --set-upstream-to origin/master master
推送到远程仓库
当你想分享你的代码时,可以将其推送到远程仓库。 命令形式:git push [remote-name] [branch-name]3.7 Git分支
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。Git 的master分支并不是一个特殊分支。 它跟其它分支没有区别。 有人把 Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来,也就是所谓“杀手”级应用。之所以几乎每一个仓库都有 master 分支,是因为git init 命令默认创建它,并且大多数人都懒得去改动它。
在本章节我们会学习到关于分支的相关命令,具体如下:查看分支
- 列出所有本地分支
git branch - 列出所有远程分支
git branch -r - 列出所有本地分支和远程分支
git branch -a1
2
3
4
5
6
7
8
9
10
11
12
13PS D:\minhang\testGit> git banch -r
git: 'banch' is not a git command. See 'git --help'.
The most similar command is
branch
PS D:\minhang\testGit> git branch -r
origin/master
PS D:\minhang\testGit> git branch -a
dev
master
* stage
remotes/origin/master
PS D:\minhang\testGit>
- 列出所有本地分支
创建分支
1
2
3
4
5
6
7
8
9
10
11
12PS D:\minhang\testGit> git branch
* master
PS D:\minhang\testGit> git branch dev
PS D:\minhang\testGit> git branch
dev
* master
PS D:\minhang\testGit> git checkout -b stage
Switched to a new branch 'stage'
PS D:\minhang\testGit> git branch
dev
master
* stage切换分支
1
2
3
4
5
6
7
8
9
10
11
12
13PS D:\minhang\testGit> git branch -a
dev
master
* stage
remotes/origin/master
PS D:\minhang\testGit> git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
PS D:\minhang\testGit> git branch
dev
* master
stage
PS D:\minhang\testGit>推送至远程仓库分支
1
2
3
4
5
6
7
8PS D:\minhang\testGit> git push origin dev
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
remote: Create a pull request for 'dev' on Gitee by visiting:
remote: https://gitee.com/fusionshen/test/pull/new/fusionshen:dev...fusionshen:master
To https://gitee.com/fusionshen/test.git
* [new branch] dev -> dev
PS D:\minhang\testGit>合并分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35PS D:\minhang\testGit> git status
On branch dev
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
PS D:\minhang\testGit> git add .
PS D:\minhang\testGit> git commit -m "测试分支合并"
[dev acff4ab] 测试分支合并
1 file changed, 2 insertions(+), 1 deletion(-)
PS D:\minhang\testGit> git push origin dev
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 320 bytes | 320.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
To https://gitee.com/fusionshen/test.git
f5d3192..acff4ab dev -> dev
PS D:\minhang\testGit> git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
PS D:\minhang\testGit> git merge dev
Updating f5d3192..acff4ab
Fast-forward
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
PS D:\minhang\testGit> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
PS D:\minhang\testGit>有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没办法合并它们,同时会提示文件冲突。此时需要我们打开冲突的文件并修复冲突内容,最后执行git add命令来标识冲突已解决
删除分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15PS D:\minhang\testGit> git branch
* dev
master
stage
PS D:\minhang\testGit> git checkout stage
Switched to branch 'stage'
PS D:\minhang\testGit> git branch -d stage
error: Cannot delete branch 'stage' checked out at 'D:/minhang/testGit'
PS D:\minhang\testGit> git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
PS D:\minhang\testGit> git branch -d stage
Deleted branch stage (was f5d3192).
PS D:\minhang\testGit>如果要删除的分支中进行了一些开发动作,此时执行上面的删除命令并不会删除分支,如果坚持要删除此分支,可以将命令中的-d参数改为-D
3.8 Git标签
像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 、v1.2等)。标签指的是某个分支某个特定时间点的状态。通过标签,可以很方便的切换到标记时的状态。
下面将学习:列出已有的标签
1
2
3
4# 列出所有tag
$ git tag
# 查看tag信息
$ git show [tag]创建新标签
1
2# 新建一个tag
$ git tag [tagName]将标签推送至远程仓库
1
2# 提交指定tag
$ git push [remote] [tag]检出标签
1
2# 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]删除标签
1
2
3
4# 删除本地tag
$ git tag -d [tag]
# 删除远程tag
$ git push origin :refs/tags/[tag]四、在IDEA中使用Git
4.1 在IDEA中配置Git
安装好IntelliJ IDEA后,如果Git安装在默认路径下,那么idea会自动找到git的位置,如果更改了Git的安装位置则需要手动配置下Git的路径。
选择File→Settings打开设置窗口,找到Version Control下的git选项:
选择git的安装目录后可以点击“Test”按钮测试是否正确配置4.2 在IDEA中使用Git
本章节我们会学习在IDEA中使用Git进行版本管理,具体包括:
在IDEA中创建工程并将工程添加至Git
将项目添加至Git管理后,可以从IDEA的工具栏上看到Git操作的按钮
当然更多的情况是用IDEA打开远程仓库将文件添加到暂存区
提交文件
将代码推送到远程仓库
从远程仓库克隆工程到本地
从远程拉取代码
版本对比
创建分支
切换分支
分支合并
五、命令行更好用
5.1 查看提交历史
git log -查看历史提交记录
在使用 Git 提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,我们可以使用 git log 命令查看。- 我们可以用 –oneline 选项来查看历史记录的简洁的版本。
git log --oneline
1
2
3
4
5
6
7
8
9PS D:\minhang\testGit> git log --oneline
1f98086 (HEAD -> master, origin/master) fix conflicts
69302e7 idea
2d5d070 (origin/dev, dev) 测试idea合并分支
b394ef7 测试IDEA提交服务器
acff4ab 测试分支合并
f5d3192 提交
7399e20 Initial commit
PS D:\minhang\testGit> - 我们还可以用 –graph 选项,查看历史中什么时候出现了分支、合并,开启了拓扑图选项。
git log --graph
1
2
3
4
5
6
7
8
9
10
11PS D:\minhang\testGit> git log --graph --oneline
* 1f98086 (HEAD -> master, origin/master) fix conflicts
|\
| * 2d5d070 (origin/dev, dev) 测试idea合并分支
* | 69302e7 idea
* | b394ef7 测试IDEA提交服务器
|/
* acff4ab 测试分支合并
* f5d3192 提交
* 7399e20 Initial commit
PS D:\minhang\testGit> - 我们也可以用 –reverse 参数来逆向显示所有日志。
git log --reverse --online
- 如果只想查找指定用户的提交日志可以使用命令:git log –author , 例如,比方说我们要找 Git 源码中 Linus 提交的部分。
git log --author=Linus --oneline -5
- 我们可以用 –oneline 选项来查看历史记录的简洁的版本。
如果你要指定日期,可以执行几个选项:–since 和 –before,但是你也可以用 –until 和 –after。例如,如果我要看 Git 项目中三周前且在四月十八日之后的所有提交,我可以执行这个(我还用了 –no-merges 选项以隐藏合并提交) 。
git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
git blame
-如果要查看指定文件的修改记录 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44PS D:\minhang\testGit> git blame .\README.md
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 1) # test
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 2)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 3) #### 介绍
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 4) 测试
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 5)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 6) #### 软件架构
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 7) 软件架构说明
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 8)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 9)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 10) #### 安装教程
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 11)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 12) 1. xxxx
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 13) 2. xxxx
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 14) 3. xxxx
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 15)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 16) #### 使用说明
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 17)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 18) 1. xxxx
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 19) 2. xxxx
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 20) 3. xxxx
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 21)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 22) #### 参与贡献
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 23)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 24) 1. Fork 本仓库
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 25) 2. 新建 Feat_xxx 分支
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 26) 3. 提交代码
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 27) 4. 新建 Pull Request
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 28)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 29)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 30) #### 特技
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 31)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 32) 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 33) 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 34) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 35) 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 36) 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
^7399e20 (fusionshen 2021-03-15 16:55:24 +0800 37) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
f5d3192c (fusionshen 2021-03-15 17:56:33 +0800 38)
f5d3192c (fusionshen 2021-03-15 17:56:33 +0800 39) #### 测试2
acff4ab3 (fusionshen 2021-03-15 20:49:17 +0800 40) 就是个测试
b394ef7c (fusionshen 2021-03-15 21:29:36 +0800 41) 测试分支合并
b394ef7c (fusionshen 2021-03-15 21:29:36 +0800 42) 测试idea将文件添加至暂存区
PS D:\minhang\testGit>5.2 版本回退
1
2
3
4
5
6
7
8
9
10
11PS D:\minhang\testGit> git log --graph --oneline
* 1f98086 (HEAD -> master, origin/master) fix conflicts
|\
| * 2d5d070 (origin/dev, dev) 测试idea合并分支
* | 69302e7 idea
* | b394ef7 测试IDEA提交服务器
|/
* acff4ab 测试分支合并
* f5d3192 提交
* 7399e20 Initial commit
PS D:\minhang\testGit>首先,Git必须知道当前版本是哪个版本,在Git中,用
HEAD
表示当前版本,也就是最新的提交1f98086...
,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
。- 穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本。 - 要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本。5.3 惯用分支,大胆commit,谨慎push(引用廖雪峰git教程)
软件开发中,经常要开发耗时很长的模块或者功能,通常有两种做法:
功能分解成小任务小模块,本地开发完成并验证通过后依次push到远程分支。以便于发现bug后本地回滚
本地开发完全并全部验证通过后统一push到远程分支。
有同时满足以上要求的吗?有!本地新增一个分支,依次开发,小任务小模块commit。
全部开发完成并本地验证通过后merge到自己主分支,优先pull。
git reset –soft
。 git add . & git commit -m “xxxxx” & git push origin master。
远程分支验证通过后,删除本地新增分支或者不删除,留作纪念。
还有没有更简单的方法?有!1
2$ git checkout master
$ git merge --no-ff feature A—B—C feature(master)
/ \
D—E—F———–G master (–no-ff)
--no-ff
会让 Git 生成一个新的提交对象。为什么要这样?通常我们把 master 作为主分支,上面存放的都是比较稳定的代码,提交频率也很低,而 feature 是用来开发特性的,上面会存在许多零碎的提交,快进式合并会把 feature 的提交历史混入到 master 中,搅乱 master 的提交历史。所以如果你根本不在意提交历史,也不爱管 master 干不干净,那么--no-ff
其实没什么用。不过,如果某一次 master 出现了问题,你需要回退到上个版本的时候,比如上例,你就会发现退一个版本到了 B,而不是想要的 F,因为 feature 的历史合并进了 master 里。
软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101
来修复它,但是,等等,当前正在dev
上进行的工作还没有提交。
并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?
幸好,Git还提供了一个stash
功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:1
2$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge现在,用
git status
查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。
首先确定要在哪个分支上修复bug,假定需要在master
分支上修复,就从master
创建临时分支:1
2
3
4
5
6
7$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$ git checkout -b issue-101
Switched to a new branch 'issue-101'现在修复bug,需要把“Git is free software …”改为“Git is a free software …”,然后提交:
1
2
3
4$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)修复完成后,切换到
master
分支,并完成合并,最后删除issue-101
分支:1
2
3
4
5
6
7
8$ git switch master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
readme.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)现在,是时候接着回到
dev
分支干活了!1
2
3
4
5
6$ git switch dev
Switched to branch 'dev'
$ git status
On branch dev
nothing to commit, working tree clean工作区是干净的,刚才的工作现场存到哪去了?用
git stash list
命令看看:1
2$ git stash list
stash@{0}: WIP on dev: f52c633 add merge工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一是用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除;
另一种方式是用git stash pop
,恢复的同时把stash内容也删了:1
2
3
4
5
6
7
8
9
10
11
12
13
14$ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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
Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)再用
git stash list
查看,就看不到任何stash内容了:1
$ git stash list
你可以多次stash,恢复的时候,先用
git stash list
查看,然后恢复指定的stash,用命令:1
$ git stash apply stash@{0}
在master分支上修复了bug后,我们要想一想,dev分支是早期从master分支分出来的,所以,这个bug其实在当前dev分支上也存在。
那怎么在dev分支上修复同样的bug?重复操作一次,提交不就行了?
有没有更简单的方法?
有!
同样的bug,要在dev上修复,我们只需要把4c805e2 fix bug 101
这个提交所做的修改“复制”到dev分支。注意:我们只想复制
4c805e2 fix bug 101
这个提交所做的修改,并不是把整个master分支merge过来。
为了方便操作,Git专门提供了一个cherry-pick
命令,让我们能复制一个特定的提交到当前分支:1
2
3
4
5
6$ git branch
* dev
master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)Git自动给dev分支做了一次提交,注意这次提交的commit是
1d4b803
,它并不同于master的4c805e2
,因为这两个commit只是改动相同,但确实是两个不同的commit。用git cherry-pick
,我们就不需要在dev分支上手动再把修bug的过程重复一遍。
既然可以在master分支上修复bug后,在dev分支上可以“重放”这个修复过程,那么直接在dev分支上修复bug,然后在master分支上“重放”行不行?当然可以,不过你仍然需要git stash
命令保存现场,才能从dev分支切换到master分支。六、贴士
Google现场教学视频https://v.qq.com/x/page/o0772kqh5iv.html?n_version=2021
Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等,但是不适合管理二进制文件。
Git push -f 慎用
优先pull,冲突只能在本地分支解决。
git rebase或者git pull –rebase可以让提交时间线整齐划一
git flow
RP和代码审查
git服务器搭建
《ProGit》进阶