JavaWeb之Git实战-Git命令大全

git实战

通常开发一个企业级项目时,需要团队内多人协作开发,不同的功能模块由不同的人员负责,这样就存在一个问题,如何将所有人的代码进行合并?再比如项目中新增了一个功能,但是上线以后发现项目中存在BUG,如何将代码回滚到前一个版本?这些都是开发中经常遇到的问题,这里就需要用到版本控制工具,常见的版本控制工具有SVN,GIT。在本章内,我们将学习Git的安装与使用。

Git简介

Git是一个分布式版本管理系统,是为了更好地管理Linux内核开发而创立的。

Git可以在任何时间点,把文档的状态作为更新记录保存起来。因此可以把编辑过的文档复原到以前的状态,也可以显示编辑前后的内容差异。

而且,编辑旧文件后,试图覆盖较新的文件的时候(即上传文件到服务器时),系统会发出警告,因此可以避免在无意中覆盖了他人的编辑内容。接下来,介绍几个Git中常用的概念。

Git数据库

Git的数据库分为远程数据库和本地数据库的两种。

  • 远程仓库: 配有专用的服务器,为了多人共享而建立的数据库。
  • 本地仓库: 为了方便用户个人使用,在自己的机器上配置的数据库。

平时用手头上的机器在本地数据库上操作就可以了。如果想要公开在本地数据库中修改的内容,把内容上传到远程数据库就可以了。另外,通过远程数据库还可以取得其他人修改的内容。Git中本地仓库和远程仓库的关系如下图:

下面对几个概念进行简单解释:

  • workspace:工作区,即存放代码的位置
  • Index:暂存区,当对代码进行修改以后,需要先将代码提交到该区域
  • Repository:本地仓库,代码提交至暂存区以后,就可以提交到远程仓库
  • Remote:远程仓库,需要和其他成员协同开发时,需要将代码提交至远程仓库

文件状态

在Git中文件状态可以粗略分为:已修改(modified)、已暂存(staged)、已提交(committed)。

修改:Git可以监听到工作目录中哪些文件被修改了,然后把修改的文件加入到modified区域。

暂存:通过add命令将工作目录中修改的文件提交到暂存区,等待committed。

提交:将暂存区文件commit至本地仓库中永久保存。

commit节点

在Git中每次提交都会生成一个节点,并且每个节点都会有一个哈希值作为唯一标志,多次提交会形成一个线性节点链(此处先暂时不考虑合并(merge)代码的情况)。如下图所示:

节点上方是通过SHA1计算的哈希值,其中C2节点包含了C1节点提交的内容,同样C3节点包含了C1、C2提交的内容。

HEAD是Git中非常重要的一个概念,也可以叫做指针或者引用,它指向任意一个节点,并且指向的节点始终为当前工作目录,也就是说当前工作目录中所显示的代码就是HEAD指向的节点。

以上一小节的图示举例,如果HEAD指向C2,那么工作目录中的代码即C2节点所对应的代码。同时,HEAD也可以指向一个分支,间接的执行分支所包含的节点。

Git分支

分支也是Git中一个相当重要的概念,当一个分支指向一个节点(节点可以理解为分支的引用),当前节点的内容即是该分支的内容,不同的分支可以存在多个。例如,在开发过程中通常会新建一个dev分支,等功能开发及测试完毕后将dev分支合并到master分支(也就是主分支)。这样再开发新功能的时候,继续在dev分支开发,而不会已经主分支的代码。

Git安装

在安装之前,需要在官网下载Git,下载地址:https://git-scm.com/

安装过程没使用默认配置,点击下一步或者next即可。

Git的使用

初始化仓库

首先在任意一个地方创建git-demo目录,然后使用init命令将该目录初始化为本地仓库,可以按照如下步骤初始化仓库。

1
2
3
mkdir git-demo
cd git-demo
git init

提交文件

在git-demo目录中新建README.md文件,并输入一定内容。首先检索文件状态。在命令行中输入如下命令:

1
git status

结果如下图:

从status响应我们可以看到‘sample.txt’目前不是历史记录对象。请首先把‘sample.txt’加入到暂存区,就可以追踪它的变更了。

将文件加入到暂存区,要使用add命令。在指定加入暂存区的文件。用空格分割可以指定多个文件。

1
git add <file>

接下来,将新建好的文件加入到索引后再次确认提交状态。

1
2
git add README.md
git status

当文件README.md已经加入到暂存区后,就可以提交文件了,此时执行commit命令后,就可以将文件提交至本地仓库。

1
git commit -m "第一次提交"

执行commit命令之后,需要设置邮箱和用户名。如下图所示

此时,设置git邮箱和用户名即可,执行如下命令,注意:此命令在整个Git使用过程中只需要设置一次即可。

1
2
git config --global user.email "you@example.com"
git config --global user.name "Your Name"

再次执行commit命令(-m后的内容是指此次提交的说明),并查看提交状态,结果如下图。

从status响应我们可以看到没有新的变更要提交。

使用log命令,我们可以在数据库的提交记录看到新的提交。结果如下图:

推送到远程仓库

为了将本地数据库的修改记录共享到远程数据库,必须上传本地数据库中存储的修改记录。

为此,需要在Git执行推送(Push)操作。执行Push之后,本地的修改记录会被上传到远程数据库。所以远程数据库的修改记录就会和本地数据库的修改记录保持同步。

Git命令大全

基本命令

创建数据库

git init

在要创建数据库的目录里执行init命令。

添加文件或目录到索引

git add <filepattern>

在filepattern可以直接指定文件名。此外,也可以指令通配字符 ( 例如“*.txt” )。如果指令 “.” , 可以将子目录里的所有文件添加到索引。

添加-p选项,就可以只添加文件修改的其中一部分。 如果添加 -i 选项,那么可以选择用对话形式显示添加在索引的文件。

提交追加到索引的文件

git commit

添加-a选项,就可以检测出修改的文件 (不包括新添加的文件),将其添加至索引并提交。这些操作只要一个指令就可以完成了。添加-m选项,就可以指令提交 “提交信息”。如果不添加-m选项,就会启动修改提交信息的编辑器。

显示修改文件清单

git status

添加-s选项,就可以不显示讲解。如果再添加-b选项,就不显示讲解,但显示分支的名称。

查看修改文件的差异

git diff

不指定选项可以显示工作树和索引的差异。添加-cached 选项可以显示索引与HEAD的差异。如果指定HEAD或提交,则可以显示工作树和指定HEAD之间的差异。

显示提交记录

git log

若要查看特定文件的提交记录,请指定文件名称。

显示提交的详细记录

git show <commit>

show命令的参数可以指定log命令参阅的提交与HEAD。

修改,移动文件的名称或目录的名称

git mv <oldfilename> <newfilename>

删除文件

git rm <file>

删除非管理对象的文件

git clean

添加-n选项就可以查看即将被删除的文件。如果添加-f选项,就立即删除文件。

在默认程序里,.gitignore指定的文件不在删除范围内。如果添加-x选项,.gitignore指定的文件也成为删除对象了。

还原正在手头上修改,还没被添加到索引里的文件

git checkout – <file>

删除已添加到索引的文件

1
git reset HEAD -- <file>

只添加已提交过的文件到索引

1
git add -u

显示分支清单

1
git branchsh

添加-a选项,就可以显示包括远端分支在内的分支清单。

创建分支

1
git branch <branchname>

修改分支的名称

1
git branch -m <oldbranch> <newbranch>

删除分支

1
git branch -d <branchname>

若有未合并到HEAD的提交,则不能删除分支。如果要强制删除未提交的分支,请添加-D选项执行。

切换分支

1
git checkout <branch>

如果添加-b 选项,只需1个命令就可以执行新建分支和已建分支之间的切换。

合并分支

1
git merge <branch>

如果添加 –no-ff 选项,就是fast-forward合并也可以建立合并提交。这是记录分支存在过的非常有用的选项。

查看标签列表

1
git tag

添加-n选项,就可以显示标签的注解。

建立标签

1
git tag <tagname>

建立含批注的标签

1
git tag -a <tagname>

删除标签

1
git tag -d <tagname>

修改最近的提交记录

1
git commit --amend

选择–amend选项提交,就可以覆盖现在的分支最前面的提交。

只修改最近的提交记录的注解

1
git commit --amend

在索引里没有注册文件的状态下,选择–amend选项以重新提交,将会显示填写注解的画面,请修改注解。

修改过去的提交记录

1
git rebase -i <commit>

如果指定提交之后再次指定提交,就会显示提交清单。请在清单里找出要修改的提交,将该行的 “pick” 改成 “edit”,之后保存并退出。

接着,编辑要修改的文件,保存文件之后指定–amend选项,以执行提交。

1
git commit --amend

最后,指定–continue选项以执行rebase。

1
git rebase --continue

只修改过去提交记录的注解

1
git rebase -i <commit>

如果指定提交之后再次指定提交,就会显示提交清单。请在清单里找出要修改的提交,将该行的 “pick” 改成 “edit”,之后保存并退出。

接着,指定–amend选项执行提交。将会显示填写注解的画面,请修改注解。

1
git commit --amend

最后,指定–continue选项以执行rebase。

1
git rebase --continue

中途停止rebase

1
git rebase --abort

指定–abort选项并执行rebase命令后,可以取消rebase。

查看HEAD的移动历史

1
git reflog

执行reflog命令,就可以查看HEAD指向过去的提交清单。

查看分支前面的移动历史记录

1
git reflog <ref>

在<ref> 指定分支名称,并执行reflog命令,过去在分支前面指向的提交清单将以下面的方式显示。

放弃最近的提交

1
git reset --hard HEAD~

放弃rebase

1
git reset --hard <commit>

首先使用reflog命令查找rebase以前的提交,确认提交的信号值或「HEAD@{数字}」值。以下的历史记录是update2提交之后,rebase命令执行2个提交之后所汇集的历史记录。71bdfbd以及HEAD@{4}是任意的提交。

取消最近的reset

1
git reset --hard ORIG_HEAD

ORIG_HEAD是指reset之前的提交,指定之后reset。

复制提交

1
git cherry-pick "<commit>"

把指定<commit>的提交复制到现在的分支。

查找包含特定注解的提交

1
git log --grep "<pattern>"

只显示提交记录里包含指定<pattern>文字的提交。

复制现有的仓库

1
git clone <url>

复制clone命令就会自动设定为追踪远程仓库 。这样,在执行push或fetch/pull命令时,即使省略repository,也可以正确地显示/读取修改内容。

复制现有的仓库

1
git remote add <name> <url>

显示远程仓库列表

1
git remote

添加-v选项就可以显示远程仓库的详细情况

在远程仓库的分支创建本地仓库的分支

1
git checkout <branch>

使用最新版本的Git,用chekout命令参数指定远程仓库的分支,就可以通过远程仓库的分支在本地仓库创建分支。如果因为您的版本太旧而不能创建,请按照下面的方法在branch命令创建分支。

在远程仓库创建分支/反映修改内容到分支

1
git push <repository> <refspec>

添加-u选项就可以追踪在远程仓库的目标分支。这样,在执行push或fetch/pull命令时即使省略了repository,也可以正确地显示/读取修改内容。

在repository,除了使用remote add命令添加的仓库名称外,也可以直接指定URL。如果省略repository,会指定被追踪的远程仓库。

在refspec可以指定分支名称。省略refspec的话,远程仓库和本地仓库所存有的分支会默认被列为目标。

查看远程仓库分支的修改内容

1
git fetch <repository> <refspec>

想确认远程仓库的修改内容,但不想反映内容到本地仓库时,可以使用fetch命令。使用fetch命令不会修改本地仓库的分支。

可以省略repository或refspec。而且省略repository与push的动作是相同的。如果省略refspec,所有的分支会默认被列为目标。

读取远程仓库的分支的修改内容

1
git pull <repository> <refspec>

通过pull命令,可以把远程仓库的修改内容反映到本地仓库的分支。贴士:「pull = fetch + merge」

可以省略repository或refspec。而且省略repository与push的动作是相同的。如果省略refspec,现在的分支会被列为目标。

删除远程的分支

1
git push --delete <repository> <branchname>

在push命令指定–delete选项和<远程仓库名称> <要削除的标签> ,然后执行。

1.7以前的Git版本不能使用–delete选项,所以请做以下指定。

1
git push <repository> :<branchname>

建立远程仓库的标签

1
git push <repository> <tagname>

添加-tags选项,就可以把本地仓库里所有的标签添加到远程仓库。

删除远程仓库的标签

1
git push --delete <repository> <tagname>

在push命令指定–delete选项和<远程仓库名称> <要削除的标签> ,然后执行。

1.7以前的Git版本不能使用–delete选项,所以请做以下指定。

1
git push <repository> :<tagname>

修改已注册的远程仓库的电子邮件地址

1
git remote set-url <name> <newurl>

把已指定名称注册的远程仓库的电子邮件地址改为<newurl> 地址。

修改已注册的远程仓库

1
git remote rename <old> <new>

在<old>把已指定名称注册的远程仓库的名称改为<new> 。

设定 用户名/电子邮件地址

1
2
git config --global user.name <username>
git config --global user.email <mailaddress>

如果不添加–global 选项,此设定只对该数据库有效。

输出彩色

1
git config --global color.ui auto

设定命令的别名

1
git config --global alias.<aliasname> <commandname>

把不需要的文件归类到非管理对象

1
echo <filename> >> .gitignore

记录为.gitignore的文件是Git的非管理对象,但是需要提交.gitignore本身。

管理空分支

1
2
cd <dirname>
touch .gitkeep

在Git, 空分支不是管理对象。因此需要把随意的文件放入分支里,使用任何文件名称都可以。按照惯例,一般使用.gitkeep名称。

显示设定清单

1
git config --global --list

通过代理主机连接http

在.gitconfig文件的http项目添加以下的设定。

1
2
[http]
proxy = <代理主机的电子邮件地址>:<代理主机的端口号码>

config命令可以使用以下设定。

1
git config --global http.proxy <代理主机的电子邮件地址>:<代理主机的端口号码>

通过需要用户认证的代理主机连接http

在.gitconfig文件的http项目添加以下的设定。

1
2
[http]
proxy = http://<用户名>:<密码>@<代理主机的电子邮件地址>:<代理主机的端口号码>

config命令可以用以下的设定。

1
git config --global http.proxy http://<用户名>:<密码>@<代理主机的电子邮件地址>:<代理主机的端口号码>

暂时保存现状的操作

1
git stash save

可以省略save,也可以指定save之后显示内容的信息。

显示暂存列表

1
git stash list

恢复暂存的操作

1
git stash pop

如果不指定参数,在对比操作中可以复原到最新的操作。指定类似stash@{1}的参数,可以复原特定的操作。

删除暂存的操作

1
git stash drop

如果不指定参数,在对比操作中会删除最新的操作。指定类似stash@{1}的参数,可以删除特定的操作。

删除所有暂存的操作

1
git stash clear