Git
知识整理
Linux基础操作
在现今的软件开发中,Linux 系统及其命令行的使用,已经是一项必不可少的技能。虽然有其他基于Git 的图形化软件,但是Git 只能通过命令行进行操作。因此,掌握一些基础的Linux 操作命令很有必要。
创建某个目录
有时我们需要创建目录,这时就需要使用命令mkdir 。通过mkdir ,可以在指定的目录下创建文件夹,其用法如下:
- 在当前目录下,创建目录
helloGit :mkdir helloGit - 在
/home 目录下,创建目录helloGit :mkdir /home/helloGit
mkdir 的其他高级用法请参考其他Linux 资料。
创建文件
创建文件可以使用命令touch ,其用法如下:
- 在当前目录下,创建文件
helloGit.txt :touch helloGit.txt - 在
/home 目录下,创建文件helloGit.txt :touch /home/helloGit.txt
进入目录
进入某个目录,需要用到命令cd ,其用法如下:
- 进入
helloGit 目录:cd helloGit`
这样的用法默认了helloGit 目录,存在于当前目录下。也可以在cd 命令中,直接指定进入当前目录: cd ./helloGit
-
进入/home/helloGit 目录: cd /home/helloGit -
返回到上一级目录: 在Linux 系统下,上一级目录可以用‘…’代替,如: #进入上一级目录
cd ..
#进入上一级目录的再上一级目录
cd ../../
#进入上一级目录下的helloGit
cd../helloGit
使用Git前的准备
安装
Git 可以使用源码安装,具体的安装过程请参考Git 官网教程或者Github 上Git 仓库的用户指南。 但对于初学用户,还是建议大家直接安装。
-
Linux 下安装: #Fedora下安装
yum install git-core
#Ubuntu等Debian类体系结构系统下
apt-get install git
-
Mac 上安装:在 Mac 上安装 Git 有两种方式。可以使用图形化的 Git 安装工具,网址为图形化Git 工具安装地址;另一种是通过MacPorts 安装。如果已经装好了 MacPorts ,请用下面的命令安装 Git :sudo port install git-core +svn +doc +bash_completion +gitweb -
Windows 下安装:在 Windows 上安装 Git ,可以使用msysGit 的项目提供的安装包,可以到 GitHub 的页面上,下载 exe 安装文件并运行: http://msysgit.github.com/ 完成安装之后,就可以使用命令行的 git 工具了。建议大家最好使用Unix 风格的shell 来运行Git 。另外,Linux 也有其他图形化的Git 工具,如Tortoisegit 。不过,还是建议大家直接使用shell 来运行Git 。
Git配置
由于Git 是一个分布式的版本控制系统,所以当利用它进行分工协作时,必须区分不同的机器。这一点可以通过配置机器的名字和邮箱完成。Git 初始使用时,也会提示进行配置。配置命令如下:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
在实际的使用过程中,可以将“Your Name” 、“email@example” 替换为自己实际的名字和邮箱。
Git本地仓库操作
如何创建一个本地版本库
首先,我们需要创建一个目录,做为我们的本地版本库,然后使用git init 命令,将其初始化为一个本地版本库,如下:
#在/home目录下,创建repo目录
mkdir /home/repo
#进入repo目录
cd /home/repo
#将repo初始化为一个本地版本库
git init
通过上述命令,即可在/home 目录下,创建repo 目录,并将其初始化为一个版本库。
如何将修改保存到暂存区
本地版本库就相当于一个存放在本地的仓库,里面记录了我们本地文件的各种版本及不同版本之间的差异。当我们添加、删除或者修改了文件之后,我们必须将修改添加至工作区以暂时保存(Git 的工作原理请认真阅读背景知识部分)。
添加修改,并保存至工作区,需要用到git add 命令,git add 命令的使用方式如下所示:
#添加所有修改git add .#添加hello.txt文件git add hello.txt
如上所示,当需要添加所有文件至工作区时,使用git add . ,如果想添加指定文件,只需要像示例中添加hello.txt 一样,将文件名做为参数名,传给git add 即可。
查看工作区状态
当你创建完helloGit.txt ,而且没有将其添加到暂存区域时,如果使用git status 命令,你会得到类似于下面的输出(中文):
# 位于分支 master
#
# 初始提交
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# helloGit.txt
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
或者这种(英文):
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: src/gitTraining
no changes added to commit (use "git add" and/or "git commit -a")
这是什么?这是提示你工作区有被修改的文件,未提交至暂存区。 当你执行完git add 之后,会得到类似于下面的输出:
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: helloGit.txt
#
或者这种:
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: src/gitTraining.java
这是在提醒你,暂存区有哪些内容需要提交到本地仓库。
其实git status 命令用来查看当前工作区的状态,即有哪些已经修改,还尚未提交到暂存区的文件。在实际的开发过程中,面对复杂的程序文件,你经常需要查看一下,自己对哪些文件做了修改,此时git status 命令就很有用了。
撤销修改
如果你不小心把不想添加的东西添加到暂存区,或者想丢弃已经添加的内容,这个时候你该怎么办呢?不用着急,这个时候git checkout 命令就可以大显身手了。
checkout 命令用法如下:
git checkout helloGit.txt
这样就能把已经添加到本地的helloGit.txt 从暂存区中移除。
如何将修改提交到本地仓库
将修改添加到暂存区,只是将你的工作暂时保存,并没有添加到本地的仓库中。这个过程可以类比写文件,将修改添加至暂存区,就相当于把内容先放入缓存区。因此,我们必须将工作区的内容提交到本地版本库去,才算是真正地保存了修改。
提交修改到本地仓库,使用命令git commit ,其使用方式如下所示:
git commit -m "示例提交"
-m 参数后面跟的是本次提交的具体内容,用来说明你这次的提交,主要是做了哪些修改,这个说明内容是必须的。
解析commit的输出结果
在执行完git commit 命令之后,会得到类似于下面的返回结果:
[master(根提交) 37302ce] 添加helloGit.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 helloGit.txt
其中:
“添加helloGit.txt” 为“-m” 的参数,即执行的命令为git commit -m "添加helloGit.txt" ;“1 file changed, 0 insertions(+), 0 deletions(-)” 提示改动信息;“37302ce” 这个字符串则是本次提交的Id ,commit Id 唯一对应一次提交。
令人惊喜的git log和git status
当执行完git commit 后,如果你试着执行以下git log 你可能会得到如下的输出:
commit 37302ce99137cf30fabc14784d23ea63cadb928b
Author: educoder <educoder@163.com>
Date: Sun Dec 24 23:35:48 2017 +0800
添加helloGit.txt
其中:
“commit 37302ce99137cf30fabc14784d23ea63cadb928b” 中的后面这一串字符就是完整的commit id ;“Author” 就是这次提交的作者,它就是我们在git config 中配置的user.name ;- 最后输出的
“添加helloGit.txt” ,是我们在提交时添加的信息。
如果有多次提交即commit ,在执行git log 时,会输出每一次的提交的具体信息。这样的话,什么时候(Date )由什么人(Author )提交了什么内容(“添加helloGit.txt ”)就一目了然了。
Git远程仓库操作
克隆操作
克隆,顾名思义,就是要获取远程版本库的完整拷贝。通过克隆操作,你可以将整个远程版本库的各种细节复制到本地,并且会建立起本地版本库和远程版本库的对应关系。
克隆操作需要用到的命令是git clone ,它的具体用法如下所示:
git clone https://sample.git
通过这样的操作,就能将远程版本库复制到本地了,而且会默认克隆到sample 文件夹下(对应于远程版本库地址中指定的sample )。同时,你也可以根据需要,指定克隆到其他目录下,其命令格式为:
git clone xxx.git "指定目录"
这样就能将代码都复制到指定目录下。
Git服务器
在团队开发中,我们必须选用一台主机做为Git 服务器来存放远程版本库。这样团队中的每个开发者,就可以基于一个共同的远程版本库进行开发。目前提供代码托管(即可以将远程版本库存放于其上的)的平台有Github 、码云等,同时我们也可以搭建一台私有的运行Git 的服务器,来做为远程Git 服务器。Github 等平台的使用,及本地Git 服务器的搭建,会在后续的实训中具体介绍。本地Git 服务器,可以配置不同的连接方式,如shell 、git 或bash 。为了给挑战者提供一个便利的实训环境,我们为每个人配置了一台本地Git 服务器,并允许以bash 方式进行操作,即可以通过类似于/home/sample.git 这种形式的地址,做为远程仓库地址进行操作,而不是像https://sample.git 这种形式。
推送本地内容到远程仓库
推送本地内容时,会将所有未推送至远程仓库的内容,都提到远程仓库。它用到的命令是git push ,使用方法如下:
git push 远程仓库名 本地分支名 远程分支名
具体的使用方法如下:
git push origin master master
这样就将本地分支的内容,推送到远程仓库origin 的master 分支了。 git push 的另外一种用法如下:
git push -u 远程仓库名 本地分支名 远程分支名
-u 参数的作用是,建立起本地master 分支和远程master 分支之间的对应关系,下一次如果再推送master 分支,就可以忽略远程分支名了,如下所示:
#初次推送
git push -u origin master master
#再次推送
git push origin master
拉取远程分支到本地
拉取远程仓库的内容到本地,需要使用git pull 命令,其命令格式为:
git pull 远程主机名 远程分支名 本地分支名
其使用示例如下:
#将远程仓库origin的master分支的内容拉取到本地master分支
git pull origin master:master
但是,在使用过程中,也可能会出现一种情况:远程分支和本地分支对同一内容做了修改,这就会导致将远程分支的修改,合并到本地分支的时候发生冲突。这个时候,可以选择解决冲突,然后合并(解决冲突会在后续的实训中介绍)。也可以选择直接强制拉取,使用远程分支的修改,覆盖本地分支的修改。强制拉取需要用到-f 参数,语法格式如下:
git pull 远程主机名 远程分支名 本地分支名 -f
具体的使用示例如下:
#将远程仓库origin的master分支的内容拉取到本地master分支
git pull origin master:master -f
Git分支管理
创建本地分支
当初始化一个版本库并进行第一次提交的时候,如果没有创建指定分支,并切换到该分支,commit 操作默认会在本地创建master 分支,并将内容提交到master 分支。一般我们会在版本库中维护一个master 分支,如下图所示:
我们在master 分支上,进行了C1 、C2 、C3 三次提交,且当前指针指向C3 提交。 一般情况下,我们只会将已经成熟的代码存放到master 分支,而将正在开发的代码或者测试版的代码放到其他分支。这时,我们就需要新建分支,以在该分支进行开发。如下图:
当我们在主分支进行了C2 提交后,新建了develop 分支,并在其上进行了两次提交。此时,工作区指针HEAD 指向develop 分支。 创建本地分支用到的命令是git branch ,而分支切换用到的命令是git checkout 。git checkout 是有很多用途的命令,在这里我们只讲它在分支操作中的使用。下面我们详细介绍这两个命令的使用。
-
分支切换 可以使用git checkout 命令切换到其他分支。如你本地有master 分支和develop 分支,目前你正处于develop 分支进行开发,现在你想切换到master 去,则可以执行下面的操作: git checkout master 这样就能切换到master 分支继续进行开发。 -
创建新的分支 当你需要创建一个新的分支的时候,可以使用git branch 命令,其具体使用格式为: git branch 新的分支名字
使用示例如下: #创建名为new_branch的新分支
git branch new_branch
-
创建新分支的同时切换 切换到一个新的分支,有一个更为简洁的命令:git checkout -b ,它的使用格式为: git checkout -b 新的分支 名字 其具体使用方法如下: git checkout -b new_branch 这样就可以创建,并切换到了new_branch 分支。
删除本地分支
现在我们来看一个实际的例子。请看下图:
首先,我们在master 工作到 C1 ,然后开始一个新分支develop 分支,做为测试版的代码分支。提交到C5 的时候,又需要临时解决一个问题,于是从C5 的地方又分出一个分支issue 。提交到C7 的时候,该issue 被解决。issue 分支已经失去其意义,则需要将其删除,以保持本地版本库分支树的干净。我们将issue 分支上的代码,合并到develop 上之后,就可将issue 分支删除。删除issue 分支后的分支树如下:
其中,C8 为合并issue 分支所进行的提交。
删除本地分支,需要用到git branch 命令,且需要-D 参数,具体命令格式为:git branch -D 需要删除的分支的名字 具体使用示例如下:
#删除develop分支git branch -D develop
示例中的命令,能够将本地分支develop 删除。
删除远程分支
删除分支用到的git 命令是git push ,在具体的使用过程中有不同的用法。
- 通过推送空分支到远程分支,实现删除。 一个删除远程分支的方法是,推送一个空分支到远程指定分支,以实现删除。推送本地分支到远程分支的方法是:
git push 远程主机名 本地分支:远程分支
与之类似,推送空分支实现删除的方法是:git push 远程主机名 :远程分支 即:前没有指定本地分支名。具体的使用示例如下:
#删除远程develop分支,其中origin为远程仓库名
git push origin :develop
-
通过delete 参数删除远程分支: 除了推送空分支到远程分支外,也可以通过delete 参数实现删除。具体的命令格式为: git push 远程主机名 --delete 远程分支名
具体使用示例如下: #删除远程develop分支,其中origin为远程主机名
git push origin --delete develop
本地分支合并
分支合并需要用到git merge 命令,具体的命令格式为:git merge 需要合并的分支 在具体使用中,如当前处于master 分支,需要将develop 分支合并到master 分支,则具体的使用方式如下:git merge develop 同时,分支合并也分为正常合并和快进式合并,通过为git merge 添加参数,即可实现不同操作。
- 快进式合并 默认情况下,
Git 执行"快进式合并",即fast-farward merge ,会直接将被合并的分支指向需要合并的分支。如下图:
当需要将右侧分支(develop )合并到左侧分支(master )时,master 分支会生成一个指针,直接指向develop 。快进式合并为默认合并方式,不需要添加任何其他参数,使用git merge 需要合并的分支 即可完成。
如图所示,Master 分支上产生了一次新的提交,也就是说生成一个新节点完成了合并,这样的话,版本演进更清晰。
下面我们以一个具体的例子,来演示一下这两种合并方式的区别:
-
创建master 分支,并在其上提交hello 文件; -
从master 分支切换到新分支develop ,并进行两次提交,分别将hello1 、hello2 两个文件提交到develop 分支; -
切换回master 分支,执行git merge develop 进行快进式合并,然后查看master 分支的日志,得到如下提示信息:
如上图可知,master 分支多了develop 分支上的两次提交信息。
- 将
master 分支回退到合并前状态,再次执行git merge --no-ff develop ,进行非快进式合并,然后再次查看日志:
可见,master 分支发生了分叉,且master 多了一次提交。
通过以上分析,两种合并方式的区别就很明显了。
日志和版本回退
强大的git log
在之前,我们已经介绍了git log 的基本使用方法,这里我们要进一步介绍git log 的使用。
- 查看提交的内容差异
git log 提供了-p 参数,用于查看每次提交之间的内容差异,如下: git log -p 即可显示每次提交之间的变化:
commit 92f972422350ef603beb2740a78f57d0f98c1738 (HEAD -> master, origin/mast
Author: educoder <user@sample.com>
Date: Sat Jan 6 15:57:52 2018 +0800
第一次提交
diff --git a/7-1.sh b/7-1.sh
new file mode 100644
index 0000000..fa7cc9c
--- /dev/null
+++ b/7-1.sh
@@ -0,0 +1 @@
+###
\ No newline at end of file
diff --git a/7-2.sh b/7-2.sh
new file mode 100644
index 0000000..fa7cc9c
--- /dev/null
+++ b/7-2.sh
@@ -0,0 +1 @@
+###
\ No newline at end of file
diff --git a/7-3.sh b/7-3.sh
new file mode 100644
index 0000000..fa7cc9c
--- /dev/null
+++ b/7-3.sh
@@ -0,0 +1 @@
+###
\ No newline at end of file
diff --git a/7-4.sh b/7-4.sh
new file mode 100644
index 0000000..fa7cc9c
--- /dev/null
+++ b/7-4.sh
而如果想限制显示的范围,则可以再添加参数用于限定:git log -p -2 如上,则仅显示最近的两次更新。 如上所示,这一选项附带了每次commit 的内容变化,这就为代码审查或者浏览某个搭档的修改内容,提供了很好的参考。
- 其他
git log 选项:
- 单词层面对比
Git 提供了--word-diff 选项,可以显示单词层面的差异。当需要在书籍、论文这种很大的文本文件上,进行对比的时候,这个功能就非常有用。 - 显示简要的增改行数
Git 提供了--stat 选项,则可以仅显示增加或者减少了多少行。 pretty 选项 使用--pretty 选项选项,可以指定不同的显示属性,如oneline 将每个提交放在一行显示。 short ,full 和 fuller 可以指定展示的信息的多少。
版本回退
git revert实现版本回退
当将有错误的文件add 进暂存区后,可以使用git reset 丢弃修改。即:git reset HEAD 文件名 但此时修改仍旧保留在工作区。
如果尚未add 进暂存区,则可以使用:git reset --hard HEAD` 这样就能彻底丢弃修改,即将修改从暂存区及工作区彻底删除。
git checkout丢弃修改
当将错误的文件add 进暂存区后,使用git checkout 无法将修改从暂存区中撤销,必须要先使用git reset 将修改从暂存区中撤销。
如果只是工作区有了修改,则可以直接使用git checkout 进行撤销,具体操作如下:
git chekcout -- hello
通过这种方式,就可将hello 文件自上个commit 之后,尚未add 进暂存区的修改丢弃。
git reset实现版本回退
git reset 也能实现版本回退,但是git revert 和 git reset 也存在一定的区别 :
git revert 是用一次新的commit 来回滚之前的commit ,git reset 是直接删除指定的commit ;- 在回滚这一操作上看,效果差不多。但是,在日后继续
merge 以前的老版本时有区别。因为git revert 是用一次逆向的commit ,“中和”之前的提交,因此日后合并老的branch 时,导致这部分改变不会再次出现。但是git reset 是把某些commit 在某个branch 上删除,因而和老的branch 再次merge 时,这些被回滚的commit 应该还会被引入; git reset 是把HEAD 向后移动了一下,而git revert 是HEAD 继续前进,只是新的commit 的内容和要revert 的内容正好相反,能够抵消要被revert 的内容。
git reset 用法如下:
git reset HEAD 回到前一次 commit 。也可以用于将错误的文件添加进暂存区后,想回退取消,如:git reset HEAD 文件名 git reset HEAD^ 回到前前一次 commit 。git reset commit 比如:commit = fa042ce57ebbe5b ,回到指定的版本,撤销也会作为一次提交进行保存。
另外git reset 也可以指定reset 的模式:hard 、soft 、mixed 、merged 、keep 。 这几种模式的差别如下:
--soft 缓存区和工作目录都不会被改变;--mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响;--hard – 缓存区和工作目录,都同步到你指定的提交。
几种模式的具体使用方法如下:
#直接丢弃工作区和暂存区的修改
git reset --hard HEAD
#暂存区内容保留,工作区修改丢弃
git reset --mixed HEAD
#暂存区和工作区内容都保留
git reset --soft HEAD
删除文件
删除文件需要用到的命令是git rm ,且git rm 有参数--cached 。
当我们需要删除暂存区或分支上的文件,同时工作区也不再需要这个文件了,可以使用:
git rm 文件路径
当我们需要删除暂存区或分支上的文件,但本地又需要使用, 只是不希望这个文件被提交到版本库,可以使用:
git rm --cached 文件路径
文件已添加至暂存区
如果文件被添加到了暂存区,这种情况下直接使用git rm file_path 会报错:
$ git rm hello.txt
error: the following file has changes staged in the index:
hello.txt
(use --cached to keep the file, or -f to force removal)
根据提示我们可以得知,这个时候,如果不想保留hello.txt ,则可以使用:git rm hello.txt -f 如果想保留hello.txt 到工作区则可以使用:git rm --cached hello.txt
文件已提交至分支
如果文件已经被提交到了某个分支,则可以使用如下命令:
#从当前分支中彻底删除‘文件路径’指定的文件
git rm 文件路径
具体使用方法如:
git rm hello.txt
或者:
#从本地版本库中将‘文件路径’指定的文件删除,并保留到工作区
git rm --cached 文件路径
具体使用方法如下:
git rm --cached hello.txt
但是无论使用哪种方式,都相当于在本地做了修改,在git rm --cached 之后,使用git status 查看版本库状态,可以得到如下输出:
$ git status
On branch master
Initial commit
Unt\fracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt
nothing added to commit but unt\fracked files present (use "git add" to t\frack)
因此,还需要通过git commit 操作将修改提交。
通过以上分析可知,从仓库中删除文件的一般过程为:
git rm <--cached> 文件名git commit -m "提交信息"
标签
在开发过程中,commit ID 是一串无序的字符,它虽然能唯一标记一次代码提交,即一个版本。但是,它很难记忆和辨识。所以,为了给不同的版本起一个容易辨识的名字,我们可以给这次提交打上一个标签,用不同的标签来对应不同的版本。这样,就相当于给这次提交生成了一个快照。实际上,在为某次提交创建标签的时候,Git 会为标签生成一个指针,以指向其对应的提交。然后,我们就可以通过标签找到对应的提交,这样对我们版本发布和代码审查都很有帮助。
如上图所示,我们为master 分支上的三次提交,分别打上0.1 、0.2 、0.3 三个标签。这样,当我们说0.1 版本的时候,就对应了第一次提交的代码。这种方式大大降低了代码审查、团队交流及版本发布的复杂性。
查看标签
查看标签需要用到git tag 命令,其具体使用示例如下: git tag
这样就能列出所有的标签,显示的标签按字母顺序排列,所以标签的先后并不表示重要程度的轻重。
如果标签过多,而你指向显示指定的某些标签,则可以使用正则表达式:
git tag -l 'v5.1.2.*'
如上,使用-l 参数,并使用v5.1.2.* 这一正则表达式,就过滤除了符合要求的标签,其中v5.1.2.* 为正则表达式,它能够匹配所有前缀为v5.1.2 的标签。实际执行过程中会得到类似于下方的输出:
v5.1.2.1
v5.1.2.2
v5.1.2.3
v5.1.2.4
上方输出信息,为我们列出了目前版本库中已有的四个标签。
创建标签
不含附注的标签
创建标签的命令格式为:
git tag 标签名 commitID
参数commitID 标识了该标签对应的代码版本,如果不提供commitID ,就默认为最近一次提交后的代码打标签。例如:
git tag v1.0
git tag v1.0 7f8buir2
语句1 表示,为最新一次提交后的代码打上v1.0 的标签;语句2 则表示,为指定的版本7f8buir2 打上标签v1.0 。
包含附注的标签
如果需要像提交代码时增加提交日志那样,为每个标签添加说明信息,则需要使用:
git tag -a 标签名 -m "说明信息"
如:
git tag -a v1.0 -m 'version 1.0'
表示为此次打的标签,增加一个version 1.0 的说明信息。
在查看标签时,可以使用git show 命令,查看某个标签的附注信息。例如:git show v1.0 表示要查看标签v1.0 对应的附注信息。
推送标签
推送指定标签
推送指定标签到远程仓库的Git 命令如下:
git push 远程主机名 tag名
其中,远程主机名 为远程Git 版本库对应的主机名,tag名 为准备推送的标签名。
该命令使用示例如下:
git push origin v1.0
该语句表示将v1.0 标签,推送到主机名为origin 对应的远程仓库。
推送全部标签
推送指定标签需要用到: git push 远程主机名 --tags 其使用方法如下: git push origin --tags 其中origin 为远程主机名,这样就能将全部标签推送至远程仓库。
删除标签
删除本地标签
删除本地标签,需要用到的命令格式为:
git tag -d 标签名
具体使用方法示例如下:
git tag -d v1.0
这样就能实现删除v1.0 标签。
删除远程标签
删除远程tag ,可以使用如下命令:
git push origin --delete tag 标签名
或者如下所示的命令:git push origin :refs/tags/<tagname> 即推送一个空的tag 名到远程仓库,其中<tagname> 指某个标签的名字。
这两种方式都能实现删除远程的指定标签。
冲突处理、忽略文件
冲突的产生
内容冲突
Git 内容冲突产生的原因是,针对版本库中某个文件的某项内容,不同的操作对其做了不同的修改,以致于在合并不同的操作时发生矛盾。比如下面的例子:
-
我们在本地master 分支,添加了文件hello ,其内容如下: Learning English is easy and simple
-
然后,我们由master 分支切换到一个新的分支develop ,并修改hello 文件内容如下: Learning English is easy & simple
随后将其提交到了本地develop 分支。 -
我们又切换回master 分支,并再次对hello 内容进行了修改: Learning English is easy or simple
这样,当我们将develop 分支合并到master 分支的时候,就会出现冲突提示如下: Auto-merging hello
CONFLICT (content): Merge conflict in hello
Automatic merge failed; fix conflicts and then commit the result.
冲突出现的原因是,我们在develop 分支和master 分支上,都对hello 文件的内容做了修改,这样当将develop 合并到master 时,Git 就不确定究竟应该采用哪个修改。
树冲突
方法文件名修改造成的冲突,称为树冲突。比如,A 用户把文件C 改名为A ,B 用户把文件C 改名为B ,那么B 合并这两个提交时,就会出现冲突:
CONFLICT (rename/rename): Rename "C"->"B" in branch "HEAD" rename
Automatic merge failed; fix conflicts and then commit the result.
此时如果使用git status 查看版本库的状态,会得到如下提示信息:
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add/rm <file>..." as appropriate to mark resolution)
added by them: A
added by us: B
both deleted: C
no changes added to commit (use "git add" and/or "git commit -a")
树冲突产生的原因是,我们将同一文件名,在不同操作中,修改为不同的名字。
解决冲突
内容冲突
当产生内容冲突时,如果你打开冲突发生的文件,你会在冲突区域发现类似于下面的内容:
<<<<<<< HEAD
Learning English is easy or simple
=======
Learning English is easy & simple
>>>>>>> develop
这个就是我们上面所举的内容冲突的例子,冲突文件的内容。从中可以看到<<<<<<< HEAD 与======= 包括的是我们当前分支的内容,而======= 和>>>>>>> develop 之间的则是需要合并过来的内容,为了解决冲突我们可以手动解决这些冲突,也可以使用图形化工具帮助解决。如果以手动方式解决,我们可以编辑冲突区域内容为我们想要的内容,比如将其修改成如下内容:
Learning English is easy and simple
然后再执行git add 和git commit 操作提交,这样就能将冲突解决了。 即解决冲突的一般过程为:
- 手动编辑冲突区域;
- 执行
git add ,将编辑提交到暂存区; - 执行
git commit ,将编辑提交到本地仓库以解决冲突。
树冲突
解决树冲突时,对于上面示例中的树冲突,如果最终决定采用文件B ,我们可以采用如下方式解决:
git rm A
git rm C
git add B
git commit
即从本地仓库中删除A 和C 文件,然后再添加B 文件并最终提交。
强制操作
强制操作的分类
使用最频繁的强制操作,主要在以下几个方面:
- 强制推送 如果远程的某个分支的内容需要被覆盖,这个时候就需要你进行强制推送,使用本地内容去覆盖该分支。
- 强制合并 如果本地分支的内容需要被远程内容覆盖,这个时候就需要强制合并远程分支内容到本地。
- 强制删除 如果你需要强制删除版本库、暂存区或者工作区的内容时,就需要强制删除。比如我们之前介绍的
checkout ,就可以使用-f 参数,强制丢弃本地修改。
强制操作方法
-
强制推送 强制推送和普通推送的区别,就在于在末尾加上了-f 参数,即: git push 远程主机名 本地分支名:远程分支名 -f
具体使用方法如下: #将本地分支强制推送到远程主机origin的master分支
git push origin master:master -f
-
强制合并 强制合并和普通合并的区别,也是其在末尾加上了-f 参数,即: git pull 远程主机名 远程分支名:本地分支名 -f
具体使用方法示例如下: #将远程master分支强制合并到本地master分支git pull origin master:master -f
忽略文件
如何忽略文件
在Git 工作区的根目录下,创建一个特殊的.gitignore 文件,把要忽略的文件名或者文件名的通配符填进去,然后将.gitignore 提交到本地仓库,这样Git 就会在你添加或者提交时,自动忽略这些文件。
自定义忽略文件
如果我们需要自己定义忽略哪些文件,就需要将其添加到.gitignore 文件中去。你可以使用文件的全称,或者使用正则匹配的通配符。如下所示:
# 忽略指定文件
HelloWrold.class
# 忽略指定文件夹
bin/bin/gen/
# 忽略.class的所有文件
*.class
# 忽略名称中末尾为ignore的文件夹
*ignore/
# 忽略名称中间包含ignore的文件夹
*ignore*/
TG参考答案
Git入门
本地版本库
第一关:本地版本库创建
#创建gitTraining文件夹
mkdir gitTraining
#进入gitTraining文件夹
cd gitTraining
#请添加初始化本地Git仓库的命令
#********** Begin **********#
git init
#********** End **********#
第2关:添加修改到暂存区
#创建gitTraining文件夹
mkdir gitTraining
#进入gitTraining文件夹
cd gitTraining
#请添加初始化本地Git仓库的命令
#********** Begin **********#
git init
#********** End **********#
#创建helloGit.txt文件
touch helloGit.txt
#请添加提交helloGit.txt到暂存区的命令
#********** Begin **********#
git add helloGit.txt
#********** End **********#
第3关:提交修改到本地仓库
#创建gitTraining文件夹
mkdir gitTraining
#进入gitTraining文件夹
cd gitTraining
#请添加初始化本地Git仓库的命令
#********** Begin **********#
git init
#********** End **********#
#创建helloGit.txt文件
touch helloGit.txt
#请添加提交helloGit.txt文件到暂存区的命令
#********** Begin **********#
git add helloGit.txt
#********** End **********#
#请添加提交helloGit.txt至本地仓库的命令
#********** Begin **********#
git commit -m "提交helloGit.txt至本地仓库"
#********** End **********#
远程版本库
第1关:clone远程版本库
#请在下面的Begin/End内填写语句以将远程版本库clone到本地
#********** Begin **********#
git clone /tmp/sample.git
#********** End **********#
第2关:添加远程版本库
#创建gitTrainging文件夹
mkdir gitTraining
#进入到gitTraining文件夹
cd gitTraining
#将gitTraining初始化为一个本地仓库
git init
#请在下面的Begin/End内填写语句添加符合要求的主机名和远程仓库
#********** Begin **********#
git remote add git /tmp/sample.git
#********** End **********#
第3关:推送本地内容到远程仓库
#创建gitTraining目录
mkdir gitTraining
#进入gitTraining目录
cd gitTraining
#将gitTraining初始化为一个本地仓库
git init
#创建helloGit.txt
touch helloGit.txt
#添加远程仓库
git remote add git /tmp/educoder.git
#将helloGit.txt添加到暂存区
git add helloGit.txt
#将helloGit.txt提交到本地仓库
git commit -m "hello Git!"
#请在下面的Begin/End内填写语句,将本地master分支的修改推送到
#远程仓库的master分支
#********** Begin **********#
git push git master master
#********** End **********#
第4关:拉取远程分支到本地
#创建gitTraining目录
mkdir gitTraining
#进入gitTraining目录
cd gitTraining
#将gitTraining初始化为一个本地仓库
git init
#创建helloGit.txt
touch helloGit.txt
#添加远程仓库
git remote add git /tmp/educoder.git
#请在下面的Begin/End内填写语句以拉取远程仓库git的master分支内容到本地
#********** Begin **********#
git pull git master master
#********** End **********#
分支管理
第1关:创建本地分支
#创建gitTraining文件夹
mkdir gitTraining
#进入gitTraining文件夹
cd gitTraining
#将gitTraining初始化为一个本地仓库
git init
#请在下面的Bein/End星号线内,使用简洁的命令,新建gitTraining分支并切换到该分支
#********** Begin **********#
git checkout -b gitTraining
#********** End **********#
#创建helloGit.txt文件
touch helloGit.txt
#添加到暂存区
git add helloGit.txt
#提交到本地仓库
git commit -m "提交helloGit.txt到本地仓库"
第2关:删除本地分支
#进入本地仓库目录
cd gitTraining
#请在下方Begin至End星号线内填写git命令以删除git分支
#********** Begin **********#
git branch -D git
#********** End **********#
第3关:删除远程分支
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以删除远程git分支
#********** Begin **********#
git push origin --delete git
#********** End **********#
第4关:本地分支合并
#进入gitTraining目录
cd gitTraining
#请在下方Begin至End星号线内填写git命令以合并git分支内容到master分支
#********** Begin **********#
git merge git
#********** End **********#
日志和版本回退
第1关:回到前一次提交
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以撤销最近一次提交
#********** Begin **********#
git revert HEAD
#********** End **********#
第2关:回到指定提交
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以回到第一次提交的版本
#********** Begin **********#
git reset --hard HEAD^^
#********** End **********#
第3关:撤销修改
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以丢弃helloGit的修改
#********** Begin **********#
git checkout -- helloGit
#********** End **********#
第4关:删除文件
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以丢弃helloGit的修改
#********** Begin **********#
git rm --cached helloGit
git commit -m "提交信息"
#********** End **********#
标签
第1关:创建标签
#创建gitTraining文件夹
mkdir gitTraining
#进入gitTraining文件夹
cd gitTraining
#将gitTraining初始化为一个本地仓库
git init
#创建helloGit.txt文件
touch helloGit.txt
#将helloGit.txt添加到暂存区
git add helloGit.txt
#将helloGit.txt提价到本地仓库
git commit -m "Git入门之标签实训第一关"
#请在下面的Bein/End星号线内填写Git命令为最近一次提交打上标签v1.0
#********** Begin **********#
git tag v1.0
#********** End **********#
第2关:推送指定标签
#进入gitTraining文件夹
cd gitTraining
#请在下面的Bein/End星号线内填写Git命令以将标签v1.0推送至远程仓库origin
#********** Begin **********#
git push origin v1.0
#********** End **********#
第3关:推送全部标签
#进入gitTraining文件夹
cd gitTraining
#请在下面的Bein/End星号线内填写Git命令为将所有标签推送至远程仓库
#********** Begin **********#
git push origin --tags
#********** End **********#
第4关:删除标签
#进入gitTraining文件夹
cd gitTraining
#请在下面的Bein/End星号线内填写Git命令以删除标签v1.0
#********** Begin **********#
git tag -d v1.0
#********** End **********#
Git进阶
冲突处理、忽略文件
第1关:解决冲突
Learning Git is easy,simple
第2关:强制操作
#创建gitTraining文件夹
mkdir gitTraining
#进入gitTraining文件夹
cd gitTraining
#将gitTraining初始化为一个本地版本库
git init
#创建helloGit2文件
touch helloGit2
#添加到暂存区
git add helloGit2
#提价到本地仓库
git commit -m "添加helloGit2"
#添加远程主机,命名为origin
git remote add origin /tmp/educoder.git
#请在下面的Bein/End星号线内填写Git命令将本地master分支强制推送到远程master分支
#********** Begin **********#
git push origin master:master -f
#********** End **********#
第3关:忽略文件
###
*.xml
|