Git基础
1 获取Git仓库的两种方式
- 将还没有进行版本控制的本地目录转换为Git仓库
- 从其余服务器
克隆
一个已存在的Git仓库
这上述的两种方式均可以让咱们在本地得到一个工做就绪的Git仓库。git
1. 1 将一个还没有进行版本控制的本地目录转换为一个Git仓库
-
将命令行窗口切换路径到须要转化为Git仓库的目录,例如我想将
gitLocalRepository
目录做为一个Git仓库,那么我首先要切换到其中githubhelloworld@surface MINGW64 ~/Desktop $ cd gitLocalRepository/ helloworld@surface MINGW64 ~/Desktop/gitLocalRepository $
-
而后执行以下代码,即可以将该目录初始化为一个本地Git仓库正则表达式
$ git init
在命令执行完以后的输出以下shell
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository $ git init Initialized empty Git repository in C:/Users/helloworld/Desktop/gitLocalRepository/.git/ helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
-
而后咱们能够打开刚才的目录查看到以下内容,结果以下数据库
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ ll -la total 8 drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 ./ drwxr-xr-x 1 helloworld 197609 0 5月 23 21:10 ../ drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 .git/ helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
咱们能够看到,在该目录下多了一个
.git
文件夹,这个文件夹就是用来存放Git的仓库配置信息的,咱们没事最好别乱修改其中的内容。咱们能够打开该目录看到如下内容vimhelloworld@surface MINGW64 ~/Desktop/gitLocalRepository/.git (GIT_DIR!) $ ll -la total 11 drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 ./ drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 ../ -rw-r--r-- 1 helloworld 197609 130 5月 23 21:14 config -rw-r--r-- 1 helloworld 197609 73 5月 23 21:14 description -rw-r--r-- 1 helloworld 197609 23 5月 23 21:14 HEAD drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 hooks/ drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 info/ drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 objects/ drwxr-xr-x 1 helloworld 197609 0 5月 23 21:14 refs/ helloworld@surface MINGW64 ~/Desktop/gitLocalRepository/.git (GIT_DIR!)
-
经过上面的初始化操做,咱们就将一个目录初始化为了一个Git本地仓库,若是该目录本来就有文件,咱们应该当即对这些文件进行追踪并进行初始提交安全
- 使用
git add <file>
对文件进行追踪 - 使用
git commit <file>
对文件进行提交
- 使用
1. 2 克隆现有仓库
-
克隆现有仓库的指令为bash
$ git clone <url>
其中
<url>
是远程仓库的地址。经过该命令,至关于基本就把远程库的全部内容复制到本地,而不只仅是最新版本的文件而已。也就是说,经过克隆的指令,你得到了远程库几乎全部内容。服务器该指令会在命令行窗口船舰一个和远程Git仓库同名的目录做为本地库。app
-
例如,咱们执行以下的指令
helloworld@surface MINGW64 ~/Desktop $ git clone https://github.com/libgit2/libgit2
就会在
Desktop
目录下创建了一个libgit2
目录,该目录就是处于就绪状态的一个本地Git仓库,咱们就能够在其中进行版本控制了 -
固然,若是你不喜欢远程库的名字,咱们还能够经过如下方式自定义一个名字
$ git clone <url> <repository name you want>
-
Git支持多种数据传输协议
http://
协议https://
协议git://
协议SSH
协议
2 记录每次更新到仓库
2.1 Git仓库中文件的状态
在咱们的工做区目录中的文件不外乎两种状态,即已跟踪
和未跟踪
状态。
已跟踪
是指文件已经被归入了版本控制的状态,在上一次快照中已经有它们的记录。在工做一段时间后,它们的状态多是未修改
,已修改
或是已放入暂存区
。简而言之,已跟踪
的文件就是Git已知的文件。- 工做区中除了
已跟踪
的文件外的全部其余文件都是未跟踪
文件。它们及不存在于上一次快照的记录中,也没有被放入暂存区。 - 像经过初始化目录造成Git本地仓库的状况,对于目录中的文件,若是没有执行过将文件放入暂存区的指令,那这样的文件就是
未跟踪
的文件。 - 而对于像经过克隆获得的仓库,在你还未进行任何修改前,其中的全部文件都属于
已跟踪
的文件。 - 文件已经进行过提交,也就是在本地库中已经有它们的记录,而以后若是咱们又编辑修改了它们,那这样的文件就会被Git标记为
已修改
文件。在工做过程当中,咱们能够选择性地将这样的文件放入暂存区
,随后再提交全部暂存的修改到本地库。
2.2 检查当前文件状态
-
咱们能够经过
git status
指令查看当前工做目录下的文件处于何种状态。 -
在没有任何东西的时候,使用
git status
指令查看当前工做目录中的文件状态信息以下helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master No commits yet nothing to commit (create/copy files and use "git add" to track) helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
- 其中第一行的
master
指明了咱们当前所处的分支,至于分支是什么咱们后面再说。On branch master
这一行也指出了咱们当前所处的分支。 No commits yet
表示咱们还未进行过任何提交nothing to commit
说明咱们当前的工做目录中没有任何能够提交的东西。(create/copy files and use "git add" to track)
这个提示咱们咱们能够经过建立或者是复制文件进来而后经过git add
命令对其进行追踪- 经过上面这一示例告诉咱们,咱们能够经过读取
git status
指令执行后输出的信息来判断文件的状态
- 其中第一行的
-
如今咱们在工做区目录中新建一个
text.txt
文件,在其中写入一行内容,具体以下this is the first time to commit
-
而后咱们能够经过
git status
命令再次查看文件的状态变化,这时候,就变成下面这样$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) test.txt nothing added to commit but untracked files present (use "git add" to track) helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
-
这时候咱们能够看到,这和上面的内容的区别主要有下面的几个
-
Untracked files:
告诉咱们有未追踪的文件,具体为test.txt
。而后还有一行提示是(use "git add <file>..." to include in what will be committed)
这个就是提示咱们,咱们能够经过
git add <file>
指令将未追踪的文件加入到将要被提交的暂存区中 -
而后下面这一行
nothing added to commit but untracked files present (use "git add" to track)
告诉咱们,尚未任何一个已经添加到暂存区以可以用于提交的文件,可是有
未追踪
的文件的出现。括号中的内容仍是提示咱们能够如何将文件添加到暂存区
-
2.3 跟踪新文件
-
能够经过
git add <file>
指令对新文件进行跟踪。例如咱们须要对新文件test.txt
文件进行跟踪,咱们就应该执行以下指令$ git add test.txt
-
执行了上述指令以后再经过
git status
指令检查文件状态就会变成下面这样helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
-
Changes to be committed:
告诉咱们有能够被转变为已提交状态的文件test.txt
,该文件为新文件,也就是刚刚新建的。 -
此时应注意,
(use "git rm --cached <file>..." to unstage)
这一句并非说使用这个指令进行提交,而是说咱们能够经过git rm –cashed <file> …
指令将文件从暂存区中撤回,若是此时咱们执行该指令,而后再执行git status
指令,那么状态就会回到上一个状态。具体以下helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git rm --cached test.txt rm 'test.txt' helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) test.txt nothing added to commit but untracked files present (use "git add" to track) helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
-
-
实际上
git add
的参数是一个文件或者是一个目录,准确地说git add
指令是这样的git add <file/dir>
若是参数是一个目录,那么就会递归地将目录下的全部文件进行追踪
-
咱们还应该注意到,在咱们进行添加到暂存区的操做(也就是
git add
)时,可能会看到这个警告的内容warning: LF will be replaced by CRLF in test.txt. The file will have its original line endings in your working directory
这个其实不是说咱们指令的执行过程当中出现了什么问题,通常咱们不用管这个警告。
-
也就是说,在执行了
git add <file/dir>
指令后,相应的文件就会被添加到暂存区中,而后这些文件也变成了已追踪
状态。Changes to be committed
表示这是已暂存状态。
2.4 暂存已修改的文件
-
如今咱们假设咱们已经有了一个状态为
已追踪
的文件,假如是tracked.txt
。 -
为了说明这种状况,咱们须要先新建一个
tracked.txt
文件,而后使用git add
指令将其加入到暂存区,而后再经过git commit
指令将其加入本地库中。至于git commit
指令,后面很快就会说到,这里咱们就先不纠结它。(在此以前咱们先将test,txt
文件从暂存区中撤回)。 -
而后咱们对
tracked.txt
文件进行修改,而后再运行git status
指令将会得到以下的信息helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: test.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: tracked.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
咱们能够看到两个状态,一个是
Changes to be committed:
,另外一个是Changes not staged for commit:
Changes to be committed:
是指已经标记为暂存状态的文件,这些文件已经加入到暂存区可是尚未提交到本地库,因此能够用于提交到本地库。咱们注意到,其中的test.txt
文件为new file
状态,也就是刚刚新建的尚未提交过的文件Changes not staged for commit:
是指已追踪
文件被修改了可是尚未加入到暂存区以备提交。已经提交过了的文件,作出了修改可是修改以后没有添加到暂存区。而后咱们能够注意到tracked.txt
是modified
状态,也就是这是这个文件不是刚新建的,而是本来就有而如今作了修改的
-
随后咱们将其添加到暂存区中,即执行
git add
指令 -
而若是咱们再将其添加到暂存区以后,再对其进行修改,而后执行
git status
指令,咱们会得到以下结果helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: test.txt modified: tracked.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: tracked.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
咱们能够看到,
tracked.txt
文件同时处于两个状态,也就是Changes to be committed:
和Changes not staged for commit:
,即同时存在于暂存区和工做区。这就说明了-
Git暂存的是你最后一次
git add
的版本的文件 -
用于提交的文件也是最后一次加入到暂存区中的文件,而不是你工做目录中最新版本的文件
-
也就是
git add
将文件存到暂存区,git commit
将暂存区的版本文件存到本地库 -
若是咱们对文件进行了修改可是没有
git add
它,它就只会停留在工做区中 -
而
git status
指令是将会进行的是这样的两两比较- 本地库的文件和暂存区的文件进行比较。若是两者不一样,则该文件将会出如今
Changes to be committed
中 - 暂存区的文件和工做区中的文件进行比较。若是两者不一样,则该文件将会出现再
Changes not staged for commit
中
上面的
stracked.txt
文件因为进行了两次修改,第一次修改而后加入暂存区,致使了本地库和暂存区中该文件的状态的不一样,而第二次仅仅是进行了修改可是没有加入到暂存区,因此致使了暂存区和工做区中的文件版本的不一样。因此最终结果就是该文件出如今了两个检测状态中。 - 本地库的文件和暂存区的文件进行比较。若是两者不一样,则该文件将会出如今
-
-
这时候就应该对
tracked.txt
再次进行git add
保证暂存区中的文件是最新版本。咱们执行了git add
以后再执行git status
就会获得如下结果helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: test.txt modified: tracked.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master)
这时候暂存区就有两个新版本的文件了,随后若是执行
git commit
指令,就会将它们一并提交到本地库中。 -
这里咱们须要说一下的就是这个
git add
指令。- 该指令是一个多功能的指令
- 它能够将一个新文件添加到暂存区中进行追踪
- 它能够将一个已追踪的文件放入暂存区
- 还能够用于合并有冲突的文件将其标记为已解决状态
- 也就是说咱们应该把这一个指令理解为“精确地将内容添加到下一次提交中”,而不只仅是“将文件添加到项目中”
2.5 状态简览
-
使用
git status
指令很详细可是未免有些繁琐 -
此时咱们可使用
-s
或者是--short
选项缩短状态命令的输出。例如-
若是咱们使用的是
git status
指令,输出以下$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: tracked.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: tracked.txt Untracked files: (use "git add <file>..." to include in what will be committed) test.txt
-
而若是加入了
-s
或者是--short
选项,输出就像下面这样$ git status -s MM tracked.txt ?? test.txt
-
新添加的
未追踪
的文件前面是两个??
-
A
表示新的文件,M
表示并不是是新的而是通过修改的文件 -
实际上,输出的左边应该分为两栏,如上的
MM
其实是两栏- 左栏指明了暂存区的状态
- 右栏指明了工做区的状态
-
例如上面的
MM
- 第一个
M
说明该文件不是新文件,可是通过了修改且并添加到了暂存区中,可是尚未提交到本地库 - 第二个
M
说明这不是一个新文件,可是通过了修改可是这个修改的版本仅仅是再工做区中进行了修改而没有添加到暂存区中 - 简言之。第一个
M
就是说该文件不是新文件,可是本地库和暂存区中该文件版本内容)不一样 - 第二个
M
说明该文件不是新文件,可是暂存区和工做区中该文件版本(内容)不一样
- 第一个
-
-
2.6 忽略文件
-
通常咱们有些文件并不须要归入Git的管理中,也不但愿它们总出如今
未跟踪
文件列表。在这种状况下,咱们能够经过创建一个.gitignore
文件,而后在其中列出要忽略的文件模式。 -
.gitignore
文件的格式规范以下- 全部空行都会被Git忽略
#
开头的行做为注释行被Git忽略- 可使用标准的
glob
模式匹配,它会递归地应用在整个工做区- 所谓的
glob
模式就是shell
所使用的简化了的正则表达式 *
表示匹配0个或者多个任意字符[abc]
表示匹配如何一个列在方括号中的内容?
表示只匹配一个任意字符[0-9]
在方括号中使用一个-
分隔连个字符,表示全部在这两个字符之间的全部字符均可以匹配**
表示匹配任意中间目录
- 所谓的
- 模式匹配能够以(
/
)开头防止递归 - 模式匹配能够以(
/
)结尾指定目录 - 要忽略指定模式之外的文件或者是目录能够在模式前加上(
!
)取反
-
例子
# 忽略全部的 .a 文件 *.a # 但跟踪全部的 lib.a,即使你在前面忽略了 .a 文件 !lib.a # 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO /TODO # 忽略任何目录下名为 build 的文件夹 build/ # 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt doc/*.txt # 忽略 doc/ 目录及其全部子目录下的 .pdf 文件 doc/**/*.pdf
-
实际上,咱们大多数时候,直接能够到github 的ignore网站去下载相应的模板就够了,而并不须要本身进行复杂的配置
-
.gitignore
文件有可能就在一个仓库的根目录下面有且仅有一个文件。实际上在仓库下的子目录中也是能够建立相应的.gitignore
文件来进行忽略文件控制的。gitignore
文件中的规则只做用在它所在的目录中,也就是只管该目录下的全部文件以及其下的全部子目录中的文件。对于同一个规则有多个声明,应该遵循就近原则吧,这里没有实验,有空再补上。
2.7 查看以已暂存和未暂存的修改
-
咱们可使用
git status
指令查看文件的状态,不过这个指令只告诉了咱们哪些文件发生了改变,而若是想要知道具体修改了什么地方,这个指令是不够详细的 -
若是咱们想要知道具体修改了什么地方,则须要用到
git diff
指令。git diff
经过文件补丁的形式可以更加详细地告诉咱们具体是哪些地方发生了什么变化-
git diff
想要查看还没有暂存的文件更新了什么内容,直接使用git diff
指令就能够了。该指令经过对比的是工做区中的文件和暂存区中相应的文件的差别,而后将其输出。对比的是工做区中的最新更改但未加入到暂存区的文件和最后一次git add
的暂存区中的文件差别。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git diff warning: LF will be replaced by CRLF in tracked.txt. The file will have its original line endings in your working directory diff --git a/tracked.txt b/tracked.txt index 0851d86..f32a8d2 100644 --- a/tracked.txt +++ b/tracked.txt @@ -1,2 +1,3 @@ add the first line second time to modify it +third time to modify it
经过该指令,咱们能够看到工做区和暂存区中的
tracked.txt
文件的差别,工做区中的文件添加了一行third time to modify it
,使用加号+
显示 -
git diff –cached
orgit diff –staged
该指令对比的是最后一次提交到本地库的文件和暂存区的最后一次加入的相应文件之间的差别。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git diff --cached diff --git a/tracked.txt b/tracked.txt index 8b13789..0851d86 100644 --- a/tracked.txt +++ b/tracked.txt @@ -1 +1,2 @@ - +add the first line +second time to modify it
咱们看到,暂存区中的
tracked.txt
和本地库中的tracked.txt
文件相比,删除了一个空行(使用-
表示删除行操做),增长了两行(用+
表示增长行操做),分别是add the first line
和second time to modify it
-
综上,
git diff
比较的是工做区和暂存区中的各自最新的相应文件之间的差别,git diff –cached
orgit diff –staged
比较的是暂存区和本地库的文件之间的差别。而后把差别部分输出显示。
-
2.8 提交更新
-
暂存区已就绪,如今咱们就能够进行提交了,不过为了保险起见,咱们最好再每一次提交以前先执行一下
git status
命令查看是否全部修改都已经加入暂存区,若是不是,能够先执行git add
命令将未加入暂存区的更改加入其中 -
使用
git commit
指令一次性提交暂存区中的全部文件。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: test.txt modified: tracked.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git commit hint: Waiting for your editor to close the file... [main 2020-05-24T09:41:33.343Z] update#setState idle [main 2020-05-24T09:42:03.355Z] update#setState checking for updates [main 2020-05-24T09:42:40.454Z] Error: net::ERR_TIMED_OUT at SimpleURLLoaderWrapper.<anonymous> (electron/js2c/browser_init.js:2623:21) at SimpleURLLoaderWrapper.emit (events.js:203:13) [main 2020-05-24T09:42:40.458Z] update#setState idle [master 9cf1dd4] this is the test.txt file first time to commit and the tracked.txt file is the first time to modify 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 test.txt
-
执行了
git commit
命令后,会弹出咱们设定的编辑器用于为本次提交写注释信息,其中默认的文本包含了再执行git commit
以前执行git status
的输出信息,可是是带注释符号的,也就是这些信息是给咱们参考的,能够看到本次提交修改了哪些文件,可是这些文件并不会真正提交上去,只有哪些前面不带#
的行才会被Git做为提交注释信息。具体以下-
弹出的原始文本信息
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # Changes to be committed: # new file: test.txt # modified: tracked.txt #
-
添加的注释信息
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # Changes to be committed: # new file: test.txt # modified: tracked.txt # this is the test.txt file first time to commit and the tracked.txt file is the first time to modify
-
-
若是咱们想要更加详细的信息出如今编辑器中,咱们能够添加
-v
选项,这时候在编辑器中出现的默认文本就是git diff
指令的输出文本,例如执行以下指令helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git diff --cached diff --git a/test.txt b/test.txt index a75d7d4..20071db 100644 --- a/test.txt +++ b/test.txt @@ -1,2 +1,3 @@ this is the first time to commit this is the second time to edit this file +this is the third time to edit this file helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git commit -v hint: Waiting for your editor to close the file... [main 2020-05-24T09:59:19.027Z] update#setState idle [main 2020-05-24T09:59:49.039Z] update#setState checking for updates Aborting commit due to empty commit message. helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $
其中弹出的编辑器的默认文本为
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # Changes to be committed: # modified: test.txt # # ------------------------ >8 ------------------------ # Do not modify or remove the line above. # Everything below it will be ignored. diff --git a/test.txt b/test.txt index a75d7d4..20071db 100644 --- a/test.txt +++ b/test.txt @@ -1,2 +1,3 @@ this is the first time to commit this is the second time to edit this file +this is the third time to edit this file
也就是说带有
git diff -cached
的输出信息
-
-
git commit -m “<message>”
将提交消息和命令放在同一行,经过-m
选项,能够直接输入本次提交的注释信息,从而不用打开编辑器编辑。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git commit -m "for testing the command 'git commit -m' " [master 3c5e45b] for testing the command 'git commit -m' 2 files changed, 2 insertions(+)
经过
-m
选项能够直接在提交的时候写注释信息,而不会弹出编辑器界面。
2.9 跳过使用暂存区域
每次先git add
而后再git commit
的作法虽然是十分周到的,可是有时候咱们未免以为有些繁琐。Git也考虑到了这个问题,因此提供了直接提交的方法。
Git提供了一个跳过使用暂存区的方式,直接将文件提交,只要在git commit
命令中加上-a
选项,Git就能够自动地把全部已经跟踪过的
文件暂存起来一并提交,从而能够跳过git add
这样一个环节。从上面的描述中咱们彷佛能够推出这一个选项只对已追踪
的文件有效,而对新建的尚未追踪
的文件不能使用,实际测试也是如此
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git commit -a -m "test 'git commit -a'" On branch master Untracked files: (use "git add <file>..." to include in what will be committed) test_03.txt nothing added to commit but untracked files present (use "git add" to track)
上面的指令就是对新建的尚未git add
过的文件直接使用git commit -a
指令出现的问题。所以,使用-a
选项,前提是工做区中的全部文件都已经至少git add
过。若是文件已追踪
就可使用该选项,示例以下:
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git commit -a -m "second time test the command 'git commit -a'" warning: LF will be replaced by CRLF in test_03.txt. The file will have its original line endings in your working directory [master 97d25c5] second time test the command 'git commit -a' 1 file changed, 1 insertion(+)
固然,这个命令很方便,可是官方文档说了:有时候这个选项会把不须要的文件添加到提交中,因此使用仍是要当心。
2.10 移除文件
-
要从Git中移除某一个文件,就必须从已追踪清单中移除(确切地说是从暂存区中移除),而后提交。
-
git rm <file>
使用该指令会将相应的文件从暂存区和工做区中移除,这样从此该文件都不会在出如今未追踪
文件清单中了。 -
可是若是只是简单地从工做目录中手动删除了一个文件,则运行
git status
时该文件名就会出如今Changes not staged for commit
部分(也就是未暂存清单中),例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ ls . test.txt test_03.txt test_rm.txt tracked.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master nothing to commit, working tree clean helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ rm test_rm.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: test_rm.txt no changes added to commit (use "git add" and/or "git commit -a")
为了避免再对该文件进行追踪,还须要执行
git rm <file>
这一指令,这才能保证该文件在下一次提交以后再也不被归入到版本管理中。 -
若是须要删除的是在以前已经修改过可是未加入到暂存区,或者是修改过并刚添加到暂存区可是尚未提交的文件,则须要
-f
选项(即force得首字母)。这是一种安全特性,防止误删还没有添加到快照得数据,这样得数据不可以被Git恢复。例如执行下面得操做若是没有-f
就会出错helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ vim test_03.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git rm test_03.txt error: the following file has local modifications: test_03.txt (use --cached to keep the file, or -f to force removal) helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git add test_03.txt warning: LF will be replaced by CRLF in test_03.txt. The file will have its original line endings in your working directory helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git rm test_03.txt error: the following file has changes staged in the index: test_03.txt (use --cached to keep the file, or -f to force removal)
- 上面得指令先是修改了
test_03.txt
文件,而后再刚修改完文件以后就执行删除文件的操做,这时候就会出现错误error: the following file has local modifications:
- 而后把该修改加入到暂存区可是尚未提交,而后就执行删除操做,照样会删错失败并出现
error: the following file has changes staged in the index:
- 这样的一种机制就尽量保证了咱们不会进行误删操做。由于Git中文件的删除都是只能删除工做区,暂存区和本地库版本一致的文件,由于这样的删除操做是可逆的,删除的文件数据能够恢复。而对于版本不一致的文件,必须加入
-f
选项,保证了你是确实要执行这种不可恢复的操做,由于这些文件的最新数据并无提交到本地库。
- 上面得指令先是修改了
-
另一种状况是,咱们想要把文件从Git仓库中删除(其实是从暂存区删除),可是仍然但愿文件能保留在工做目录中。也就是说咱们不想让Git追踪该文件可是咱们又想让它存在仓库的目录中,实际上就相似那种应该要被忽略的可是忘记忽略了如今忽然想起来要忽略的文件。对于这样的状况,咱们可使用
git rm –cached <file>
指令,该指令实际上就是将文件从暂存区中删除,而保留工做区中的文件,想要在后期再也不管理此文件仍是须要将其手动加入到.gitignore
文件中。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git rm --cached test_03.txt rm 'test_03.txt' helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ vim test_03.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: test_03.txt Untracked files: (use "git add <file>..." to include in what will be committed) test_03.txt helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git commit -a -m "test 'git rm --cached '" [master 872ec7b] test 'git rm --cached ' 1 file changed, 3 deletions(-) delete mode 100644 test_03.txt
实际上执行这一指令就是将文件从暂存区进行删除了,可是文件还保留在工做区中,文件仍是能够被Git检测到
-
git rm
指令能够删除目录,也可使用glob
模式 -
上面说的彷佛有些复杂,实际上能够总结以下:
- 对于工做区,暂存区和本地库三个区中版本一致的文件能够执行
git rm
指令 - 而执行
git rm <file>
指令会将文件从暂存区和工做区删除,执行以后文件再也不存在,而后再提交,本地库就会记录该文件已经被删除,从此该文件就再也不存在了,确定就不能再对其进行版本控制了 git rm –cached
指令就只是将文件从暂存区删除,可是工做区还保留着该文件。这一指令是对于那种忘记忽略某些文件时能够采起的操做,由于该操做不会将工做区中的文件删除,咱们在执行该指令以后将这些文件手动添加到.gitignore
文件中,从此Git就再也不对其进行追踪了。可是若是咱们不将其加入到.gitigore
文件中,在从此它们仍是要被Git检测到,也就是它们仍是属于要就行版本控制的文件。这一指令实际上并不会使得执行了该指令后的文件自动被Git忽略。- 对于那些在工做区和暂存区中的版本和本地库的版本不一致的文件,若是要执行删除操做,必需要加上
-f
选项,表示强制删除。由于对于这样的文件,若是删除,使用Git是没法找回它们的全部历史数据的,由于最新的修改没有保存在本地库,因此要使用-f
以确保你是在知道删除该文件的后果的状况下进行的操做
- 对于工做区,暂存区和本地库三个区中版本一致的文件能够执行
2.11 移动操做
-
Git并不会显示跟踪文件的移动操做。由于若是在Git中对文件进行了重命名,文件中的数据并不会发生改变。可是Git却可以推断出这是一次重命名操做。
-
Git提供了一条命令用于移动文件和对文件重命名,这条命令以下
$ git rm <from_file> <to_file>
-
执行这一条命令,示例以下
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git mv test_03.txt test_03 helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: test_03.txt -> test_03
咱们能够看到Git确实可以知道这是一次重命名操做。至于这是怎么实现的,咱们到后面再说。
-
实际上
git rm <from_file> <to_file>
指一条指令,至关于执行如下三条指令的结果mv <from_file> <to_file> git rm <from_file> git add <to_file>
若是咱们经过这样分开的操做,Git也能判断出这是一次重命名操做。因此说在Git中咱们能够经过两种方式对文件进行重命名。可是明显使用
git mv
方便得多。分开操做实例以下helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ mv test_03 test03 helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git rm test_03 rm 'test_03' helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git add test03 warning: LF will be replaced by CRLF in test03. The file will have its original line endings in your working directory helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: test_03 -> test03
咱们能够看到,Git一样能够知道咱们进行了一次重命名的操做。
-
有时候咱们可能要使用其余工具批量重命名。这时候咱们要记得在提交以前删除旧文件名,添加新文件名。
2.12查看提交历史
-
在几个进行了若干次修改和提交以后,或者是咱们刚克隆了一个仓库咱们可能想回顾一下提交的历史,这时候咱们就能够经过
git log
命令实现这一种需求 -
这里咱们先补一下
git diff
的知识-
示例
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git diff warning: LF will be replaced by CRLF in test03. The file will have its original line endings in your working directory diff --git a/test03 b/test03 index e0a9216..3ec31f6 100644 --- a/test03 +++ b/test03 @@ -2,3 +2,4 @@ test "git commit -a" second time test "git commit -a" test rm -f git rm --cached +add a line
-
git diff
输出的各行的含义-
以下这两行是因为设置了unix和win之间换行符的转换致使产生的警告,能够忽略
warning: LF will be replaced by CRLF in test03. The file will have its original line endings in your working directory
-
diff --git a/test03 b/test03
-
表示的是输出的结果是git 格式的
diff
-
而后要比较的是变更前的a版本的
test03
和变更后的b版本的test03
之间的差别
-
-
index e0a9216..3ec31f6 100644
index e0a9216..3ec31f6
表示变更先后两个文件的哈希值100644
表示文件的权限,644
表示这是一个普通文件
-
下面这两行
--- a/test03 +++ b/test03
--- a/test03
前面带有---
表示变更前的版本- 那么后一个就是带有
+++
就表示变更后的版本
-
@@ -2,3 +2,4 @@ test "git commit -a"
@@ -2,3 +2,4 @@
分为两个部分,前半部分-2, 3
表示这是变更前的版本2, 3
表示是对比从变更前的版本的第2行开始以后的3行的内容。后半部分+2, 4
表示对比的是变更后的版本的第2行开始的后4行test "git commit -a"
表示变更前版本提交时的注释说明
-
下面这几行是差别对比的内容
second time test "git commit -a" test rm -f git rm --cached +add a line
- 前面带有
+
号表示改动后的版本相对改动前的版本增长的内容 - 前面带有
-
号表示改动后的版本相对于改动前的版本删除的内容
- 前面带有
-
-
-
一个
git log
的简单示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) Author: Square John <1042009398@qq.com> Date: Mon May 25 08:33:31 2020 +0800 renamed test_03 to test03 commit 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:29:47 2020 +0800 renamed test_03.txt to test_03 commit 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:19:18 2020 +0800
- 执行该命令以后,咱们会得到咱们全部提交的历史记录
- 每一条记录的显示格式为
commit 717a7d2979a28eb269a6397141f4c90a688bdba8 [(HEAD -> master)]
- commit以后的一串字符是每一次提交文件的SHA-1校验和
(HEAD -> master)
中HEAD
所在的位置表示当前文件的版本,master
表示当前所在分支
Author: Square John <1042009398@qq.com>
这一行明显就是提交的做者信息,包括做者名字和邮箱Date: Mon May 25 08:33:31 2020 +0800
这一行表示提交日期renamed test_03 to test03
这一行就是咱们的提交说明
-
git log
的几个经常使用选项介绍-
-p
or--patch
显示每一次提交所引入的差别(按补丁的格式输出) -
-num
其中num
表示一个正整数,表示最多显示num
条记录 -
上两个选项的示例
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log -p -6 commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) Author: Square John <1042009398@qq.com> Date: Mon May 25 08:33:31 2020 +0800 renamed test_03 to test03 diff --git a/test_03 b/test03 similarity index 100% rename from test_03 rename to test03 commit 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:29:47 2020 +0800 renamed test_03.txt to test_03 diff --git a/test_03.txt b/test_03 similarity index 100% rename from test_03.txt rename to test_03 commit 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:19:18 2020 +0800 commit test_03.txt diff --git a/test_03.txt b/test_03.txt new file mode 100644 index 0000000..e0a9216 --- /dev/null +++ b/test_03.txt @@ -0,0 +1,4 @@ +test "git commit -a" +second time test "git commit -a" +test rm -f +git rm --cached
咱们能够看到,加入了
-p
选项以后,输出中就多了git diff
的输出部分 -
--stat
输出每次提交的粗略统计信息。例如$ git log -6 --stat commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) Author: Square John <1042009398@qq.com> Date: Mon May 25 08:33:31 2020 +0800 renamed test_03 to test03 test_03 => test03 | 0 1 file changed, 0 insertions(+), 0 deletions(-) commit 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:29:47 2020 +0800 renamed test_03.txt to test_03 test_03.txt => test_03 | 0 1 file changed, 0 insertions(+), 0 deletions(-) commit 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:19:18 2020 +0800 commit test_03.txt test_03.txt | 4 ++++ 1 file changed, 4 insertions(+)
增长了
--stat
选项以后,就再也不输出每次提交引入的差别的详细信息了,而是显示其中的粗略的统计信息。例以下面这几行test_03.txt | 4 ++++ 1 file changed, 4 insertions(+)
表示本次提交在
test_03.txt
中增长了4行,本次提交有一个文件发生了改变,增长了4行 -
--pretty
可用于指定不一样格式用于输出提交历史。它有下面几个子选项-
oneline
表示一条记录使用一行来进行输出。示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --pretty=oneline 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) renamed test_03 to test03 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 renamed test_03.txt to test_03 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 commit test_03.txt 872ec7b2a068b676dc0a62d1c34b211be869bf3b test 'git rm --cached ' 6fb5ea099be4353c4a15a604127dfd30ad5566ea modified test_03.txt 5467b52f33083d64b49931ec7fcae79a71ac7699 delete test_rm.txt dbf3a645b1afd2164aa670733e8304bae0cde601 test rm command 97d25c59f4583ed4e532466113e47ee7244b4c3c second time test the command 'git commit -a' ef3fc04aa669d3813257bf652d5f782bab59f31c create the test_03.txt file 3c5e45bfcc16c7172fdf4ef76a0500a4cc92f39b for testing the command 'git commit -m' 41fe2d33654009b729c4d8988374282bad69db0f this is the second time to edit this file 9cf1dd4c8558bcfff0e4cf88d923313d36e5671f this is the test.txt file first time to commit and the tracked.txt file is the first time to modify b958cb41c923adde860490de6660481e4dc30825 create the tracked.txt file
输出格式为完整的
SHA-1
校验和以及提交说明 -
short
表示使用简短的形式进行输出 -
full
和fuller
顾名思义,就是详细输出和更详细输出 -
format
能够用于定制输出的格式-
format
的经常使用选项以下表选项 说明 %H 提交的完整哈希值 %h 提交的简略哈希值 %T 树的完整哈希值 %t 树的简略哈希值 %P 父提交的完整哈希值 %p 父提交的简略哈希值 %an 做者名 %ae 做者电子邮箱 %ad 做者的修订日期(可使用 --date= 选项 来定制格式) %ar 做者的修订日期(按多久之前的方式来显示) %cn 提交者的名字 %ce 提交者的电子邮箱 %cd 提交的日期(参照上面) %cr 提交的日期 %s 提交说明 这里咱们应该能够注意到,修改者和提交者可能不是同一我的
-
format
的示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --pretty=format:"hash:%h ; authorname:%an ; email:%ae ; %s" hash:717a7d2 ; authorname:Square John ; email:1042009398@qq.com ; renamed test_03 to test03 hash:6b78b5e ; authorname:Square John ; email:1042009398@qq.com ; renamed test_03.txt to test_03 hash:0fe3c8d ; authorname:Square John ; email:1042009398@qq.com ; commit test_03.txt hash:872ec7b ; authorname:Square John ; email:1042009398@qq.com ; test 'git rm --cached ' hash:6fb5ea0 ; authorname:Square John ; email:1042009398@qq.com ; modified test_03.txt hash:5467b52 ; authorname:Square John ; email:1042009398@qq.com ; delete test_rm
-
-
graph
经过增长一些ASCII
字符串来形象地展现分支和合并历史。须要和--pretty
的--oneline
或者是--format
结合使用
-
-
-
git log
经常使用选项选项 说明 -p 按补丁格式显示每一个提交引入的差别 --stat 显示提交的文件修改的统计信息 --shortstat 只显示--stat中最后的行数添加删除统计 --name-only 仅在提交信息后显示已修改的文件清单 --name-status 显示新增、修改和删除的文件清单 --abbrev-commit 仅显示SHA-1校验和的前几个字符 --relative-date 使用较短的相对时间而不是完整的日期格式显示日期 --graph 在日志旁使用ASCII图形显示分支与合并历史 --pretty 自定义日志的输出显示格式 --oneline --pretty=oneline --abbrev-commit合用的简写 -
--name-status
示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --name-status -6 commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) Author: Square John <1042009398@qq.com> Date: Mon May 25 08:33:31 2020 +0800 renamed test_03 to test03 R100 test_03 test03 commit 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:29:47 2020 +0800 renamed test_03.txt to test_03 R100 test_03.txt test_03 commit 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 Author: Square John <1042009398@qq.com> Date: Mon May 25 08:19:18 2020 +0800 commit test_03.txt A test_03.txt commit 872ec7b2a068b676dc0a62d1c34b211be869bf3b Author: Square John <1042009398@qq.com> Date: Sun May 24 20:59:18 2020 +0800 test 'git rm --cached ' D test_03.txt commit 6fb5ea099be4353c4a15a604127dfd30ad5566ea Author: Square John <1042009398@qq.com> Date: Sun May 24 20:56:53 2020 +0800 modified test_03.txt M test_03.txt commit 5467b52f33083d64b49931ec7fcae79a71ac7699 Author: Square John <1042009398@qq.com> Date: Sun May 24 20:35:38 2020 +0800 delete test_rm.txt D test_rm.txt
R100
表示重命名A
表示新增长文件D
表示删除文件M
表示修改文件
-
--relative-date
示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --relative-date -6 commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) Author: Square John <1042009398@qq.com> Date: 3 hours ago renamed test_03 to test03 commit 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 Author: Square John <1042009398@qq.com> Date: 3 hours ago renamed test_03.txt to test_03 commit 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 Author: Square John <1042009398@qq.com> Date: 3 hours ago commit test_03.txt commit 872ec7b2a068b676dc0a62d1c34b211be869bf3b Author: Square John <1042009398@qq.com> Date: 14 hours ago test 'git rm --cached ' commit 6fb5ea099be4353c4a15a604127dfd30ad5566ea Author: Square John <1042009398@qq.com> Date: 14 hours ago modified test_03.txt commit 5467b52f33083d64b49931ec7fcae79a71ac7699 Author: Square John <1042009398@qq.com> Date: 15 hours ago delete test_rm.txt
-
--oneline
示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --oneline 717a7d2 (HEAD -> master) renamed test_03 to test03 6b78b5e renamed test_03.txt to test_03 0fe3c8d commit test_03.txt 872ec7b test 'git rm --cached ' 6fb5ea0 modified test_03.txt 5467b52 delete test_rm.txt dbf3a64 test rm command 97d25c5 second time test the command 'git commit -a' ef3fc04 create the test_03.txt file 3c5e45b for testing the command 'git commit -m' 41fe2d3 this is the second time to edit this file 9cf1dd4 this is the test.txt file first time to commit and the tracked.txt file is the first time to modify b958cb4 create the tracked.txt file
-
-
日志的限制输出长度
-
-num
只显示前num
个提交历史。咱们要注意,这里所说的前num
个是最新的num
个,并且是按照时间降序排列,也就是时间越大(越新)排在越前面,最新版排在第一个位置,以此类推。实际上git log
的默认输出的排序方式就是这样 -
--since
表示自某一个日期开始其后的全部版本-
示例
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --since=10.hours --relative-date commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (HEAD -> master) Author: Square John <1042009398@qq.com> Date: 3 hours ago renamed test_03 to test03 commit 6b78b5e394c7cb2e587160f3fd11048ca09a6f92 Author: Square John <1042009398@qq.com> Date: 3 hours ago renamed test_03.txt to test_03 commit 0fe3c8d1ccc682d907c2627cec27ac3f6f1d7fa8 Author: Square John <1042009398@qq.com> Date: 3 hours ago commit test_03.txt
--since=10.hours
表示自10个小时前以后的全部提交记录,也就是前10个小时的提交历史。 -
可用格式
该选项可用格式十分丰富。可用
2020-05-20
这样的格式来表示某一天,也可使用3 minutes ago
这样的相对时间格式
-
-
--until
和--since
正好相反,--until
表示要显示的是从最开始一直到某一个时间点为止的全部提交历史。示例helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git log --until=10.hours --relative-date commit 872ec7b2a068b676dc0a62d1c34b211be869bf3b Author: Square John <1042009398@qq.com> Date: 14 hours ago test 'git rm --cached ' commit 6fb5ea099be4353c4a15a604127dfd30ad5566ea Author: Square John <1042009398@qq.com> Date: 14 hours ago modified test_03.txt commit 5467b52f33083d64b49931ec7fcae79a71ac7699 Author: Square John <1042009398@qq.com> Date: 15 hours ago delete test_rm.txt commit dbf3a645b1afd2164aa670733e8304bae0cde601 Author: Square John <1042009398@qq.com> Date: 15 hours ago test rm command commit 97d25c59f4583ed4e532466113e47ee7244b4c3c Author: Square John <1042009398@qq.com> Date: 15 hours ago second time test the command 'git commit -a' commit ef3fc04aa669d3813257bf652d5f782bab59f31c Author: Square John <1042009398@qq.com> Date: 15 hours ago create the test_03.txt file
上面的例子就显示了凑从提一次提交知道10个小时以前的全部提交记录。
-
-
过滤匹配指定条件的提交记录
-
--author
选项表示只显示指定做者的提交记录 -
--grep
选项用于指定搜索关键字,只显示提交说明中
包含指定关键字的提交记录 -
咱们能够同时指定多条
--author
and--grep
过滤条件- 默认只要提交记录只要有一个条件匹配就会被显示出来
- 添加
--all-match
选项以后只有那些知足全部过滤条件的提交记录才会被显示出来 - 也就是对于具备多个过滤条件的状况,默认使用
||(或)
的逻辑关系,只要知足其中一个条件就会被输出。--all-match
就是&&(与)
的逻辑关系,只有知足全部条件才会被输出
-
-S
它接受一个字符串参数,而且只会显示那些文件数据中
增长或者删除了包含该字符串
的提交历史记录。 -
--path
path
指定一个路径,只显示该路径下的目录和文件的提交历史记录。该选项应该放在最后面 -
用于限制日志输出长度的选项总结以下表
选项 说明 --author 只显示指定做者修改的提交记录 --grep 只显示提交说明中包含--grep选项指定的关键字的提交记录 -num 只显示最后的num个提交记录 --since or --after 只显示指定日期以后的提交记录 --until or --before 只显示指定日期以前的提交记录 --committer 只显示指定提交者提交的记录 -S 只显示文件数据中添加或者是删除了包含-S选项指定的字符串的提交记录
-
-
--no-merges
隐藏合并提交的历史记录
3 撤销操做
在本节中咱们将学习几个撤销咱们所作的修改的工具。注意,其中有些撤销操做是不可逆的,这是在Git中会由于操做失误而致使前面所做的工做丢失的几个少有的地方之一。
3.1 修补提交
$ git commit --amend
这个命令会将暂存区中的文件提交。若是自上次提交以来,你对文件尚未作任何修改,那么Git对文件的快照不变,使用该命令修改的只是提交信息。
- 经过该指令提交,本次的提交说明会覆盖上一次的提交说明
- 最终你只有一个提交,第二次的提交将代替第一次提交的结果
- 使用该命令,其效果就好像前一次的提交从未出现过同样,
它不会出如今仓库的历史版本中
- 修补提交最大的价值是能够稍微改进你最后的提交。而没必要由于像因为忘记暂存几个文件而须要对这些文件进行屡次无修改的提交。
- 试想一下,原本你是想一次性提交三个文件,结果你对文件修改完了,可是只将其中的一个文件加入了暂存区,而后提交了这个文件,提交以后你才意识到忘记将另外两个放入暂存区而致使内有提交。随后你又将另一个文件放入暂存区而忘记了另一个文件(真是夸张),而后又一次提交,而后又想起还有一个,而后再重复。像这样,提交了三次,可是在三次提交中,咱们只在第一次提交前修改了文件,原本能够一次性提交做为一个版本,如今却成了三个版本。这样的情况发生得过多,就会致使仓库版本过多且过于繁琐。因此,
git commit --amend
指令的价值就在这里,能够覆盖掉前面一些比较没有意义的提交。
3.2 取消暂存的文件
git reset HEAD <file>
指令用来从暂存区撤销对该文件的暂存。可是咱们要知道这是一个危险的命令。这里就先学习这一个,后面会有关于reset
指令的详细介绍。
3.3 撤销对文件的修改
git checkout -- <file>
命令能够用来撤销咱们在工做区对文件所作的全部修改。这是一个危险的命令,一旦对某个文件执行了该指令,则这个文件在工做区中所作的任何修改都会消失,Git会使用最近提交的版本覆盖它。
除非你本身确实清楚不想要那个文件在工做区中所作的全部修改了,不然就不要使用它。
若是咱们想保留对那个文件的修改可是如今仍然要撤销这些修改,咱们可使用后面将会学到的Git分支
的作法,这一般是更好的作法。
咱们要清楚,在Git种几乎全部的已提交的内容都是能够恢复的,甚至是上面所说的git commit --amend
指令覆盖的提交记录。可是,任何咱们还未提交的内容一旦消失,咱们颇有可能就再也找不回来了。
4 远程仓库的使用
4.1 查看远程仓库
-
经过
git remote
命令能够列出咱们指定的全部的远程服务器的简写。例如helloworld@surface MINGW64 ~/Desktop/temp (master) $ git remote cono
-
添加
-v
选项能够列出全部的咱们指定的远程仓库的简写和对应的URL。例如helloworld@surface MINGW64 ~/Desktop/temp (master) $ git remote -v cono https://github.com/srevinsaju/conozco.git (fetch) cono https://github.com/srevinsaju/conozco.git (push)
4.2添加远程仓库
-
使用
git clone
命令就能够自动将一个远程仓库克隆到当前目录下,具体的命令为$ git clone [<repository_name>] <remote_url>
- 若是不指定仓库名称,就会使用远程仓库的名称。经过该指令,Git会默认为该远程仓库创建一个叫作
origin
的简写名称 - 该命令是将远程库完整地拷贝到本地。克隆完成后咱们就得到了一个处于工做状态的Git仓库,能够直接就在本地进行修改。
- 若是不指定仓库名称,就会使用远程仓库的名称。经过该指令,Git会默认为该远程仓库创建一个叫作
-
git remote add <simple_name> <remote_url>
该命令用于添加一个新的Git远程仓库,其中simple_name
是该仓库的简写名称。`注意:这里所说的以及上面所说的远程仓库的简写名称的意思是说从此咱们能够经过该简写代替远程仓库的url和远程仓库进行交换数据。-
实际上,添加一个远程仓库的意思就是将远程仓库的URL记录到本地,同时为其起了一个简写名称。添加了一个远程仓库和克隆一个远程仓库是由很大区别的
添加一个远程仓库
的意思是说在本地库的基础上,经过git remote add
命令,将一个远程仓库的URL记录下来,并用一个简写名称表明该URL。此后咱们就能够访问该远程仓库了,若是咱们有写入的权限,咱们还能够修改该远程库。可是添加了一个远程仓库并无直接将远程库的内容下载到本地,只是在本地库增长了一个有关该远程库的记录,至关于咱们如今知道了这样一个远程库的存在。要添加一个远程库,首先要在本地有一个仓库。
克隆一个远程库
就是直接将远程库上的全部内容都复制到本地,直接在本地得到一个和远程库同样的本地库。同时该本地库会默认添加了一个简写为origin
de 远程库,该远程库就是所克隆的远程库
-
git remote add
仅仅是使得咱们知道了有某一个远程库的存在,咱们想要得到其中的内容,咱们还有执行git fetch <remote_repository>
这一个命令,其中remote_repository
能够是一个远程库的连接,也能够是其简写名称。 -
可是执行了
git fetch
命令只是将远程库的数据下载到了本地,它并不会自动将远程库的分支内容和本地库的分支内容合并起来。咱们能够经过本地访问<remote_repository>/branch_name
这样的方式访问到该远程库的某一个分支的内容 -
若是须要将
git fetch
得到的远程库某一个分支的内容与本地库的某一分支内容进行合并,须要使用git merge
命令。假设当前处于本地库的master
分支(默认),而后咱们想将远程库的master
分支与其合并,则应该在执行了git fetch
以后执行$ git merge <simple_name/master>
simple_name
为远程库简写。 -
git pull <simple_name>
指令就至关于git fetch <simple_name>
加git merge <simple_name/cur_branch>
。若是咱们设置了当前分支跟踪远程分支该,指令在下载完远程库的内容到本地以后自动将远程库的被跟踪分支的内容和本地的当前分支的内容进行合并。这一指令显然更加简洁,可是若是合并时有冲突,仍是须要进行手动合并。
-
4.3 从远程仓库中抓取和拉取
git fetch <remote_repository>
用于从远程仓库抓取内容到本地,可是不会合并内容,合并内容须要git merge
git pull <remote_repository>
用于从远程仓库拉取内容,而且将拉取的远程库中的被当前本地库中分支跟踪的分支与本地库的当前分支的内容进行合并
4.4 推送到远程仓库
git push <remote_repository> <master>
命令用于将本地库中的master
分支推送到remote_repository
远程库中- 只有当你拥有
remote_repository
的写入权限,而且在你最后一次获取该远程库的数据以后尚未人进行过推送的状况下,你的推送才会被远程库服务器接受。只要其中一个条件不知足,就会被拒绝。对于第二种状况,就是在你推送以前已经有人进行过推送,那么咱们想要推送咱们的内容,必须先要拉取远程库的最新数据,而后在这个最新版本上再进行修改以后才能推送成功。
4.5 查看某个远程仓库
-
git remote show <remote_repository>
命令用来查看remote_repository
远程库的信息。例如helloworld@surface MINGW64 ~/Desktop/temp (master) $ git remote show cono * remote cono Fetch URL: https://github.com/srevinsaju/conozco.git Push URL: https://github.com/srevinsaju/conozco.git HEAD branch: master Remote branch: master tracked Local ref configured for 'git push': master pushes to master (up to date)
-
该命令会向咱们展现以下信息
- 咱们抓取和推送的远程仓库的URL
- 咱们当前处于远程库中的
[master]
分支 - 分支的跟踪信息,例如上面的例子中,
master
分支就正处于被跟踪状态 - 该指令还会告诉咱们哪些远程分支再也不本地,哪些分支被远程服务器移除了
- 咱们经过
push
以及pull
命令能够进行自动合并的相应的本地和远程分支组合
4.6 远程仓库的重命名和移除
git remote rename <from_name> <to_name>
命令用来对某一个远程库进行重命名。- 可是须要注意的是,这个命令是更改远程库在本地的简写名称。该命令不会真的将远程服务器上的远程库名字改了,而只是本地保存的对远程库的简写名称改了,而且会将该远程库在本地的全部引用到该简写名称的地方都改了。好比说当初咱们使用
fetch
拉取了一个远程库的内容,在没有重命名以前咱们经过<from_name/master>
这样的方式访问master
分支的内容,可是重命名以后要将from_name
换成to_name
- 综上,该命令实际上也就是改了远程库的简写名称,从此全部须要使用
from_name
的地方都将要被改成使用to_name
- 可是须要注意的是,这个命令是更改远程库在本地的简写名称。该命令不会真的将远程服务器上的远程库名字改了,而只是本地保存的对远程库的简写名称改了,而且会将该远程库在本地的全部引用到该简写名称的地方都改了。好比说当初咱们使用
- 若是咱们想要移除一个远程库,可使用
git remote remove/rm <remote_repository>
命令来移除一个远程库。一样须要注意的是:该命令只是将本机上的与远程库相关的全部内容从本机上删除了,而不是将远程库从远程服务器上删除了
- 总结:上面的无论是对远程库进行重命名也好仍是移除远程库也好,说的都是将本机上有关远程库的信息进行修改,这些操做都不会对远程服务器上的远程库产生任何影响。
重命名只是更改了本机对远程库的称呼,移除只是将远程库的内容从本机上移除
5 打标签
咱们能够在某些提交中打上一个标签,以示本次提交的重要性。好比说,咱们在某些提交中打上这样的标签v1.0 , v2.0
来表示发布节点。
5.1 列出标签
-
git tag
命令用于列出当前仓库中全部的标签。标签按照名字排序而不是按照时间排序 -
git tag -l/--list <regex>
能够按照指定的模式列出符合条件的标签,例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git tag v0.9 v1.0 v1.0.0-lw helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git tag -l v1.0 v1.0 helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git tag --list v1.* v1.0 v1.0.0-lw
- 使用
git tag
命令会将完整的标签列表给列举出来。而增长了-l/--list
选项以后就只列出符合其后的模式字符串regex
的标签 - 注意:
使用通配模式必需要有
-l/--list选项
- 使用
5.2 建立标签
Git支持两种标签:轻量标签(lightweight)
和附注标签(annnotated)
5.2.1 附注标签
-
附注标签是存储在Git数据库中的一个完整对象。其中包括
- 打标签者的名字
- 打标签者的电子邮箱地址
- 打标签的日期和时间
- 一个标签信息
-
附注标签是能够
被校验
的,而且可使用GUN Privacy Guard(GPG)签名并验证。咱们一般建议打附注标签。 -
打附注标签的命令很简单,就是在
tag
指令中加入-a
选项,具体以下$ git tag -a tagName -m "tag message"
-m
选项就是用于指定标签信息的,若是没有该选项,就会和提交的时候同样,会跳出编辑器要求你输入标签信息 -
可使用
git show <tagName>
来查看某一个标签的标签信息以及本次提交的提交信息。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git show v1.2.0 tag v1.2.0 Tagger: Square John <1042009398@qq.com> Date: Tue May 26 10:15:36 2020 +0800 this's version 1.2.0 commit b5a7b0648a22c54c12eb20d9978c860196a1b43e (HEAD -> master, tag: v1.2.0) Author: Square John <1042009398@qq.com> Date: Tue May 26 10:13:16 2020 +0800 in test.txt add a line ,to verify tag command diff --git a/test.txt b/test.txt index 20071db..02aaa68 100644 --- a/test.txt +++ b/test.txt @@ -1,3 +1,4 @@ this is the first time to commit this is the second time to edit this file this is the third time to edit this file +git tag git tag git tag -a v1.2 -m "hhh" diff --git a/test03 b/test03 index e0a9216..3ec31f6 100644 --- a/test03 +++ b/test03 @@ -2,3 +2,4 @@ test "git commit -a" second time test "git commit -a" test rm -f git rm --cached +add a line
- 第4行是打标签的人的名字和email地址
- 第5行是打标签的时间
- 第7行是标签信息
- 其后是本次提交的信息以及
git --diff
的差别信息
5.2.2 轻量标签
-
轻量标签本质上就是将提交校验和存储到一个文件中,此外没有保存任何其余的东西。至关于一个临时的标记
-
打一个轻量标签不须要任何额外的选项,只要在
git tag
以后跟上标签名就能够了,即$ git tag <tagName>
-
使用这样的方式打标签,使用
git show <tagName>
命令咱们不会看到任何有关改标签的标签信息。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git show v1.0.0-lw commit 717a7d2979a28eb269a6397141f4c90a688bdba8 (tag: v1.0.0-lw, tag: v1.0) Author: Square John <1042009398@qq.com> Date: Mon May 25 08:33:31 2020 +0800 renamed test_03 to test03 diff --git a/test_03 b/test03 similarity index 100% rename from test_03 rename to test03
该命令输出的只有本次提交的信息。
5.3 后期打标签
Git支持对过往的提交记录打标签
- 咱们只须要使用
git log
命令列出相应的提交记录,而后获知提交记录的校验和(或者是部分校验和) - 而后就只须要在
对当前版本打标签的命令
后面加上须要打标签的历史提交记录的校验和
就能够了- 打附注标签
git tag -a <tagName> -m “<tag msg>” <checksum>
。其中checksum
为须要打标签的提交记录的校验和 - 打轻量标签同理
- 打附注标签
5.4 共享标签
- 默认状况下,使用
git push
命令并不会将在本地打的标签传送到远程仓库的远端服务器去。 - 必需要将标签显式推送到远端服务器上,使用
git push <remoteRepository> <tagName>
命令能够将指定的标签推送到远端服务器上 - 可是若是一次一个这么推送,若是标签过多就会很麻烦。此时可使用
git push <remoteRepository> --tags
一次性将全部本地创建的标签推送到远端服务器上。此后,被人克隆该远程库上的内容或者是从中拉取数据,都会获得这些标签。 git push <remoteRepository> --tags
不会区分这些标签是轻量标签仍是附注标签,二者都会被推送上去。没有任何一个选项支持分开将两种类型的标签分别批量上传。
5.5 删除标签
-
可使用
git tag -d <tagName>
来从本地仓库上删除一个标签,可是这并不会将远端服务器上的远程库上的相应标签也删除。 -
要从远程服务器上的相应仓库中删除一个标签,须要使用
git push <remoteRepository>: refs/tags/<tagName>
这一个命令。该命令有两种变体-
git push <remoteRepository> :refs/tags/<tagName>
是使用:
号前面的空值代替原有的tagName
,从而能够高效删除该标签 -
另外还有一种更加直观的方式:
$ git push <remoteRepository> --delete <tagName>
-
5.6 检出标签
- 可使用
git checkout <tagName>
这一个命令来查看tagName
指向的文件版本 checkout
命令会使得仓库处于头指针分离(detacthed HEAD)
的状态。在这种状态下,若是你作了某些修改而后提交了它们,标签不会发生变化,可是新提交的内容将不属于任何一个分支,而且将没法访问,除非是经过使用确切的提交时候的哈希值才能对其进行访问。- 在
头指针分离
的状态下,若是咱们须要进行修改提交,一般咱们应该新建一个分支。
6 Git别名
-
Git不会在咱们输入部分命令时自动推断出咱们想要的命令,这也就意味着咱们必须牢记每个命令。
-
可是有些命令很长,不只难记,并且敲这些命令也须要大量时间。
-
此时咱们能够为这些命令起一个简短的别名,从此就可使用这个别名代替其指代的命令。
-
git config
命令能够修改config
文件,而咱们又能够在config
文件中配置相应的Git命令别名,因此咱们能够经过git config
命令来给Git命令起别名。 -
例如
helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git config --global alias.cfg 'config --global' helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git cfg alias.cmmta 'commit -a -m' helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $
$ git config --global alias.cfg 'config --global'
为config --global
起了一个别名为cfg
,从此就可使用cfg
代替config --global
了- 而后使用
cfg
又给commit -a -m
起了一个别名为cmmta
。
-
若是是须要为外部命令定义别名,就须要在外部命令以前加上一个
!
号。例如helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git cfg alias.md '!mkdir' helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ git md hahaha helloworld@surface MINGW64 ~/Desktop/gitLocalRepository (master) $ ls . hahaha/ test.txt test03 tracked.txt
就为外部命令
mkdir
定义了一个别名为md
。
7 经常使用命令小结
7.1 获取和添加仓库
-
克隆一个现有仓库
$ git clone <remoteRepository>
-
初始化当前目录为本地仓库
$ git init
-
在本地库添加一个远程库
$ git remote add <simpleName> <remoteRepository> $ git fetch <simpleName> $ git merge <simpleName/brunchNname>
若是本地库当前分支设置了跟踪远程库的某一分支
$ git remote add <simpleName> <remoteREpository> $ git pull <simpleName>
7.2 使用Git进行文件的版本管理
-
检查Git仓库目录中的文件状态
-
查看文件状态
$ git status
-
以简洁的方式查看文件的状态
$ git status -s/--short
-
-
将文件添加到暂存区
$ git add <file/dir>
-
将暂存区的文件一次性提交到本地库
$ git commit [-m "<msg>"]
-
对于已跟踪的文件,作修改以后能够跳过使用暂存区直接提交修改到本地库
$ git commit -a [-m "<msg>"]
-
查看已暂存和未暂存文件的修改(差别)
-
查看暂存区和工做区中文件的差别
$ git diff
-
查看本地库和暂存区中文件的差别
$ git diff --cached/--staged
-
-
移除文件
-
文件和本地库版本一致的文件
-
同时从暂存区和工做目录中移除文件,此后版本管理中将再也不有它
$ git rm <fileName>
-
仅将文件从暂存区中删除,工做区中的文件保留,其后可将其加入到忽略文件列表中不进行版本管理
$ git rm --cached <fileName>
-
-
对于和本地库版本不一致的文件的移除,均须要在上述命令中添加
-f
选项进行强制删除-
删除暂存区和本地库中的文件
$ git rm -f <fileName>
-
仅删除暂存区中的文件
$ git rm -f <fileName>
-
-
-
移动(重命名)文件
$ git rm <from_file> <to_file>
或者
$ mv <from_file> <to_file> $ git rm <from_file> $ git add <to_file>
-
查看提交记录
$ git log
其后可跟各类选项定制输出。
-
忽略的文件的列表和规则在
.gitignore
文件中
7.3 撤销操做
-
修补提交
$ git commit --amend [-m "<msg>"]
-
取消暂存的文件
$ git reset HEAD <file>
-
撤销对文件的修改
$ git checkout -- <file>
7.4 远程仓库的使用
-
查看远程仓库
$ git remote
-
添加远程仓库
$ git remote add <simpleName> <remoteREpository>
-
从远程仓库中抓取和拉取内容
-
抓取内容
$ git fetch <simpleName>
-
拉取内容
$ git pull <simpleName>
-
-
推送到远程仓库
$ git push <simpleName> <localBranch>
-
查看某一个远程仓库信息
$ git remote show <remoteRepository>
-
远程仓库的重命名
$ git remote rename <fromFile> <toFile>
-
远程仓库的移除
$ git remote rm/remove <remoteRepository>
7.5 打标签
-
查看完整标签列表
$ git tag
-
建立标签
-
建立附注标签
$ git tag -a <tagName> [-m "<msg>"]
-
建立轻量标签
$ git tag <tagName>
-
查看标签信息
$ git show <tagName>
-
-
补打标签
$ git tag [-a] <tagName> [-m "<msg>"] <checksum>
-
共享标签
-
共享一个标签
$ git push <remoteRepository> <tagName>
-
共享所有标签
$ git push --tags
-
-
删除标签
-
从本地库删除一个标签
$ git tag -d <tagName>
-
删除远端服务器上的远程库的标签
-
方式1
$ git push <remoteRepository> :refs/tags/<tagName>
-
方式2
$ git push <remoteRepository> --delete <tagName>
-
-
-
查看某个标签对应文件版本信息
$ git checkout <tagName>
7.6 Git别名
-
为Git内部命令起别名
$ git config --global alias.<title> '<command>'
-
为外部命令起别名
$ git config --global alias.<title> '!<command>'