Git使用教程七

本文主要介绍4个Git命令,它们分别是stash、tag、rm和mv命令。stash用于暂存或者恢复当前工作目录的内容。tag用于创建,列出,删除或验证使用GPG签名的标签。rm用于删除Git版本库中跟踪的文件或者目录。mv命令用于移动或重命名文件,目录或符号链接。

git stash

git stash命令用于将更改储藏在脏工作目录中

git stash list [<options>]
git stash show [<options>] [<stash>]
git stash drop [-q|--quiet] [<stash>]
git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
	     [-u|--include-untracked] [-a|--all] [-m|--message <message>]
	     [--] [<pathspec>…?]]
git stash clear
git stash create [<message>]
git stash store [-m|--message <message>] [-q|--quiet] <commit>

创建stash和应用stash

如果当前的工作目录有更改,但是并没有add进暂存区,这时切换到其它分支,可能会得到如下的类似提示信息。

$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        README
Please commit your changes or stash them before you switch branches.
Aborting

提示信息表示这是一个error错误,如果想要checkout到其它分支,那么当前分支的本地更改会被覆盖掉。请在切换分支之前先commit更改或者stash它们。

$ git stash
Saved working directory and index state WIP on develop: 8e14913 add 003 line

调用没有任何参数的git stash相当于git stash save。

当使用过stash之后,工作目录就干净了。

$ git status
On branch develop
Your branch is up to date with 'origin/develop'.

nothing to commit, working tree clean

当前工作目录被stash后,可以使用如下命令查看stash信息。

$ git stash list
stash@{0}: WIP on develop: 8e14913 add 003 line

$ git stash show
 README | 1 -
 1 file changed, 1 deletion(-)

使用stash命令存储的修改,可以使用git stash list列出,使用git stash show进行检查,并使用git stash pop恢复。

$ git stash pop
On branch develop
Your branch is up to date with 'origin/develop'.

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

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (47950c0bb30647426d3ec80a5d34789f0cd1f673)

当使用git stash pop,已经stash的目录也会被同步删除。

其它方式应用stash和删除stash记录

假设某个分支有三次不同的stash信息,stash信息如下:

$ git stash list
stash@{0}: WIP on develop: 8e14913 add 003 line
stash@{1}: WIP on develop: 8e14913 add 003 line
stash@{2}: WIP on develop: 8e14913 add 003 line

如果想要重新应用刚刚操作的stash,还可以使用其它方式的应用方式。如果想应用更早之前的stash,可以通过名字指定它,像这样:gitstash apply stash@{2}。如果不指明,Git默认使用最近的储藏并尝试应用它。

$ git stash apply
On branch develop
Your branch is up to date with 'origin/develop'.

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

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

apply选项只尝试应用stash的工作——储藏的内容仍然在栈上。要移除它,可以运行 git stash drop再加上希望移除的储藏的名字。

$ git stash drop stash@{1}
Dropped stash@{1} (bc524720ac0cb528f18dba88d45f0573a914217f)

从stash中创建分支

$ git stash branch dev
Switched to a new branch 'dev'
On branch dev
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

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (ed311ed34c0d6a0032fd32d90042fa0de5ad39d7)

git tag

git tag命令用于创建,列出,删除或验证使用GPG签名的标签对象。

创建tag

Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。

创建一个含附注类型的标签非常简单,用 -a (译注:取 annotated 的首字母)指定标签名字即可:

$ git tag -a V1.0 -m "my version v1.0"

创建一个轻量级tag。

$ git tag simple1.0

查看所有的tag。

$ git tag
V1.0
V1.1
simple1.0

查看某个tag的详细信息。

$ git show V1.1
tag V1.1
Tagger: sunny <sunny@git.com>
Date:   Mon Oct 7 08:13:18 2019 +0800

my version v1.1

commit 8e14913d5a59d60b114e55f73c473ac66bd4255b (HEAD -> develop, tag: V1.1, tag: V1.0, origin/develop, dev)
Author: sunny <sunny@git.com>
Date:   Wed Oct 2 17:22:28 2019 +0800

    add 003 line

diff --git a/README b/README
index 983ef01..5d90604 100644
--- a/README
+++ b/README
@@ -1,4 +1,5 @@
 add 001 line
 add 002 line
 add important line
+add 003 line

删除本地某个tag。

$ git tag -d simple1.0
Deleted tag 'simple1.0' (was 8e14913)

删除远程某个tag。

$ git push origin :simple1.0
remote: Powered By Gitee.com
To https://gitee.com/xxxx/gitest.git
 - [deleted]         simple1.0

如果要一次推送所有本地新增的标签上去,可以使用 --tags 选项:

$ git push origin --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 155 bytes | 155.00 KiB/s, done.
Total 1 (delta 0), reused 1 (delta 0)
remote: Powered By Gitee.com
To https://gitee.com/xxxx/gitest.git
 * [new tag]         V1.1 -> V1.1
 * [new tag]         simple1.0 -> simple1.0

git rm

git rm用于删除Git版本库中跟踪的文件或者目录,如果某个文件还没有使用add命令添加至暂存区,这时候使用git rm是不起作用的。

git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>…?

使用git rm命令删除某个只在工作目录的文件,但是并没有添加至Git版本库中,这时候命令的执行结果如下:

$ git rm 2.txt
fatal: pathspec '2.txt' did not match any files

如果某个文件已经保存至暂存区,但是并没有提交至Git仓库,这时命令执行结果如下:

$ git rm 1.txt
error: the following file has changes staged in the index:
    1.txt
(use --cached to keep the file, or -f to force removal)

如果在命令中添加一个--cached参数,会将暂存区中的该文件的记录删除,相当于该文件没有被add之前的状态,但是文件还存在于工作目录。

$ git rm --cached 1.txt
rm '1.txt'

但是如果使用了-f参数,这时候文件将会从暂存区和工作目录删除,平常使用中一定要慎用-f命令,因为这种情况下删除的文件相当于永久删除了,Git版本库和工作目录都将不存在该文件的记录了。

$ git rm -f 1.txt
rm '1.txt'

如果某个文件已经提交至Git仓库,但是在工作目录已经更改,但是更改后的文件并没有提交至Git仓库,这时命令执行结果如下:

$ git rm 1.txt
error: the following file has local modifications:
    1.txt
(use --cached to keep the file, or -f to force removal)

如果想要直接使用rm删除一个文件,而且不需做任何强制措施,那么该文件必须是在Git仓库,而且状态必须是clean状态。

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

处于clean状态的文件,可以使用git rm直接删除,一旦命令执行成功,这时候工作空间的文件会被删除。

$ git rm 1.txt
rm '1.txt'

使用rm删除后的文件,这时候在暂存区还存在该文件索引的,文件状态是deleted状态的,但是,使用git status查看已经删除的文件状态如下:

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

        deleted:    1.txt

已经删除的文件,一定要再执行一次commit才可以,这样在工作区和暂存区以及Git仓库才算完成了一次完整的删除操作。

删除文件夹和删除某个文件有所不同,需要借助于-r参数。当然了待删除的文件夹也应该是已经提交至Git仓库的,并且是clean状态的,如下是执行删除文件夹的命令:

$ git rm -r sub
rm 'sub/sub01.txt'
rm 'sub/sub02.txt'

rm

rm也是一个删除命令,首先需要知道一点,rm和git rm是不一样的,在命令操作中有git关键字,意味着这种操作是受Git管制的。但是rm这种命令方式,其实是一种暴力方式的操作,rm会直接将文件删除,有点类似Window系统上的删除文件,而且是Shift+Delete的操作方式。

如果使用rm删除了文件,这种情况下仅仅是删除了物理文件,但是并没有从Git记录中删除。

git mv

git mv命令用于移动或重命名文件,目录或符号链接。

git mv <options>…? <args>…?
git mv [-v] [-f] [-n] [-k] <source> <destination>
git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>

使用git mv操作的目标也必须位于Git版本库中,如果源文件位于Git暂存区,这时候执行mv重命名时,文件仍然位于Git暂存区。

如果源文件位于Git仓库,重命名后文件会被转移至Git暂存区。

$ git mv 5.txt 555.txt

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

        renamed:    5.txt -> 555.txt

如果查看状态是renamed,那么在commit时,注意一定要两个文件都同时提交到Git仓库。如果使用git status查看本次操作,其实5.txt状态是deleted状态的,而555.txt是newFile。

其实git mv相当于运行了3条命令:
mv 5.txt 555.txt
git rm 5.txt
git add 555.txt

如果git mv用于移动文件到目录时,那么目标目录必须是现有的已存在目录才可以,否则可能会变成了文件重命名。

小结

Git的介绍基本告一段落了,有些操作还没有涉及,比如.gitignore文件的操作,基本每个项目都会使用忽略文件,相关操作可以参看网上其它文章。

Git某些命令的使用在本系列中也只是简单的记录一下,想要达到熟练使用还有很长的一段路要走。

参考资料

Git教程

Git Community Book 中文版

评论

您确定要删除吗?删除之后不可恢复