progit 笔记 02 - Git 基础
本部分涵盖 Git 使用中的各种基本命令,包括初始化仓库(repository)、开始或停止跟踪(track)文件、暂存(stage)或提交(commit)更改;配置 Git 来忽略指定的文件和文件模式、撤销错误操作、浏览项目的历史版本以及不同提交(commits)间的差异、推送(push)到远程仓库以及从远程仓库拉取(pull)文件等。
获取 Git 仓库
在现有的项目目录中初始化仓库
1
$ git init
该命令将创建一个 .git
子目录,这个子目录包含初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 这时仅做了初始化,项目文件还没有被跟踪。通过以下命令跟踪并提交
1
2
3
$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'
这样就得到了一个跟踪着若干文件的 Git 仓库。
克隆现有仓库
使用 git clone
命令克隆一个现有仓库,比如克隆 libgit2
:
1
$ git clone https://github.com/libgit2/libgit2
这会在当前目录下创建一个 libgit2
目录,并在该目录下初始化一个 .git
文件夹,从远程仓库拉取所有数据存放在 .git
文件夹内,然后从中读取最新版本的拷贝,并且存放在应该在的位置。
如果想要自定义本地仓库的名字,可以使用下面的命令:
1
$ git clone https://github.com/libgit2/libgit2 mylibgit
这样在本地创建的仓库名字就会变为 mylibgit
。
检查当前文件状态
使用 git status
命令查看仓库中哪些文件处于什么状态。如果检查刚克隆后的 libgit2
仓库,会看到类似输出:
1
2
3
4
5
$ git status
On branch master
nothing to commit, working directory clean
此时新建一个 README
文件,再次使用 git status
命令时,将看到一个新的未追踪文件:
1
2
3
4
5
6
7
8
9
10
11
$ echo 'My Project' > README
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
在状态报告中可以看到 README
文件出现在 untracked files
下面。未跟踪的文件意味着 Git 在之前的快照(提交)中没有这些文件;Git 不会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”。
跟踪新文件
使用 git add
命令开始跟踪一个文件。git add
命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。比如要跟踪 README
文件:
1
$ git add README
此时再运行 git status
检查状态,会看到 README
文件已被跟踪,并且处于暂存状态:
1
2
3
4
5
6
7
8
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README
这里可以看到文件在 Changes to be committed
下面,说明是已暂存状态。
暂存已修改的文件
如果修改了 README
文件,再次运行 git status
时将会看到:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README
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: README
这时 README
文件同时出现在等待提交区(暂存区)和未暂存区,是因为 Git 只暂存了上次运行 git add
命令时的那个版本,而不是当前修改过的版本。
在 Changes not staged for commit:
看到 README
说明已修改了但是没有放到暂存区。要暂存这次更新,需要运行 git add
命令。 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。
将修改后的 README
文件添加到下一次提交,并再次查看状态:
1
2
3
$ git add README $ git status On branch master
No commits yet
Changes to be committed: (use "git rm --cached ..." to unstage) new file: README
状态简览
git status
命令输出当前仓库状态信息。使用 git status -s
或 git status --short
获得更为紧凑的状态信息: bash $ git status -s A NEWADD M README MM UNSTAGED ?? LICENSE.txt
上面的报告表示,NEWADD
文件前的 A
表示该文件是新添加的并且放入了暂存区,README
前的 M
表示文件被修改了并且放入了暂存区,UNSTAGED
文件前左边的 M
表示被修改并且放入了暂存区,右边的 M
表示文件被修改但还未放入暂存区,LICENSE.txt
前的 ??
表示文件未被追踪。
忽略文件
创建 .gitignore
文件来忽略日志文件,或者编译过程中创建的临时文件等。
1
2
3
4
5
$ cat .gitignore
*.[oa]
*~
第一行表示忽略后缀名是 o
或者以 a
的文件,第二行告诉 Git 忽略所有以 ~
符号结尾的文件。
文件 .gitignore
的格式规范如下:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
glob 模式是指 shell 所使用的简化了的正则表达式。
GitHub 有一个十分详细的,针对数十种项目及语言的 .gitignore 文件列表,你可以在 https://github.com/github/gitignore 找到它.
查看已暂存和未暂存的修改
git diff
命令查看未暂存的文件更新了哪些部分:
1
2
3
4
5
6
7
8
9
$ git diff
diff --git a/UNSTAGED b/UNSTAGED
index f3229c5..eb1ae45 100644
--- a/UNSTAGED
+++ b/UNSTAGED
@@ -1 +1 @@
-..
+...
(END)
若要查看已暂存的将要提交到下次更新里的内容,可以使用 git diff --cached
或者 git diff --staged
(Git >= 1.6.1)命令查看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git diff --staged
diff --git a/NEWADD b/NEWADD
new file mode 100644
index 0000000..e69de29
diff --git a/README b/README
index 0e6bdc2..e00a688 100644
--- a/README
+++ b/README
@@ -1 +1 @@
-my project.
+my project..
diff --git a/UNSTAGED b/UNSTAGED
index 9c558e3..f3229c5 100644
--- a/UNSTAGED
+++ b/UNSTAGED
@@ -1 +1 @@
-.
+..
(END)
还可以通过
git difftool
命令使用图形化界面分析文件差异
提交更新
当确保修改过的文件都已暂存(通过 git add
添加修改过但还未暂存的文件),就可以准备提交了。运行提交命令 git commit
:
1
$ git commit
该命令会启动文本编辑器,以便输入本次提交更新的说明。编辑器会显示下面的文本信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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: NEWADD
# modified: README
# modified: UNSTAGED
#
# Changes not staged for commit:
# modified: UNSTAGED
#
# Untracked files:
# LICENSE.txt
#
默认的提交信息会包括最后一次运行 git status
的输出,放在注释行里,并且开头有一空行,用来输入提交说明。另外可以使用 git commit -m
来将提交信息和命令放在同一行进行提交:
1
2
3
4
$ git commit -m "Story 182: Fix benchmarks for speed"
[master c800db7] Story 182: Fix benchmarks for speed
3 files changed, 2 insertions(+), 2 deletions(-)
create mode 100644 NEWADD
此时便完成了提交。
跳过使用暂存区域
使用 git commit -a -m
来跳过暂存步骤,Git 会自动把所有已经跟踪过的文件暂存起来一并提交:
1
2
3
4
5
6
7
8
9
10
11
12
$ git status
On branch master
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: CONTRIBUTING.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m "added new benchmarks"
[master 4520c36] added new benchmarks
1 file changed, 1 insertion(+)
移除文件
要从 Git 中移除某个文件,要从已跟踪的文件清单中移除(从暂存区移除),然后提交。使用 git rm
命令,连带从工作目录中删除指定文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是手动从工作目录中删除文件,运行 git status
时就会在 “Changes not staged for commit”
部分(也就是_未暂存清单_)看到:
1
2
3
4
5
6
7
8
9
$ rm PROJECTS.md
$ 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: PROJECTS.md
no changes added to commit (use "git add" and/or "git commit -a")
然后需要再运行 git rm
操作来移除此文件,这样下次提交时,该文件就不再纳入版本管理了。
1
2
3
4
5
6
$ git rm PROJECTS.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: PROJECTS.md
如果删除之前,已修改过并且放入了暂存区,必须使用强制删除选项 -f
。
如果我们想把文件从暂存区删除,但是不想删除本地文件的话,使用 --cached
选项:
1
$ git rm --cached README
移动文件
要在 Git 中修改文件名,可以使用下面的命令:
1
$ git mv file_from file_to
此时查看状态信息:
1
2
3
4
5
6
$ git mv README README.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README -> README.md
该命令相当于:
1
2
3
$ mv README README.md
$ git rm README
$ git add README.md
查看提交历史
使用 git log
命令查看并回顾提交历史:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git log
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
(END)
使用 -p
参数,来显示每次提交的内容差异。也可以加上 -2
来显示仅最近2次提交:
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
$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison number
diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
spec = Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = "simplegit"
- s.version = "0.1.0"
+ s.version = "0.1.1"
s.author = "Scott Chacon"
s.email = "schacon@gmail.com"
s.summary = "A simple gem for using Git in Ruby code."
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
end
end
-
-if $0 == __FILE__
- git = SimpleGit.new
- puts git.show
-end
使用 --stat
选项,显示每次提交的简略信息:
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
$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison number
Rakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
lib/simplegit.rb | 5 -----
1 file changed, 5 deletions(-)
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
README | 6 ++++++
Rakefile | 23 +++++++++++++++++++++++
lib/simplegit.rb | 25 +++++++++++++++++++++++++
3 files changed, 54 insertions(+)
(END)
使用 --pretty=<>
选项来用不同的方式展示提交历史,如:
1
2
3
4
5
$ git log --pretty=online
ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD) changed the verison number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
(END)
使用 format
参数来定制显示的记录格式:
1
2
3
4
5
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 12 years ago : changed the verison number
085bb3b - Scott Chacon, 12 years ago : removed unnecessary test code
a11bef0 - Scott Chacon, 12 years ago : first commit
(END)
更多选项查看 pretty-formats
如果使用 online
或 format
选项时配合 --graph
使用,会添加一些 ASCII 字符串来形象的展示分支、合并历史:
1
$ git log --pretty=online --graph
git log
详细参数参考 git-log
撤消操作
有些撤消操作是不可逆的。 这是在使用 Git 的过程中,会因为操作失误而导致之前的工作丢失的少有的几个地方之一。
当我们提交完成后发现漏掉了文件,或者提交信息填写错误,可以运行带有 --amend
选项的提交命令,重新提交。
1
2
3
4
5
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
这个命令会将暂存区的文件提交;如果暂存区没有文件(自上次提交后没有修改,如上次提交后马上执行此命令),那么快照会保持不变,只是提示修改提交信息。最终只会有一个提交,第二次提交将替代第一次提交。
取消暂存的文件
使用 git reset HEAD <file>...
来取消暂存某个文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: README.md -> README
modified: CONTRIBUTING.md
$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: README.md -> README
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: CONTRIBUTING.md
modified: CONTRIBUTING.md
撤消对文件的修改
使用 git checkout -- <file>...
来把文件还原到上次提交时的样子。如还原 CONTRIBUTING.md
文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
git checkout -- [file]
是一个危险的命令,Git 只是拷贝了另一个文件来覆盖它,所以对它做的修改历史都会消失。
远程仓库的使用
查看远程仓库
使用 git remote
命令查看已经配置了的远程仓库服务器。如果你试着在自己克隆的项目目录运行 git remote
那么至少能看到 origin
:这是 Git 给克隆的仓库服务器的默认名字: ```bash $ git clone https://github.com/schacon/ticgit $ cd ticgit $ git remote
使用 git remote -v
会显示远程仓库的 Git 简写以及对应的 URL。
1
2
3
4
5
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
如果远程仓库不止一个(与多个协作者合作的仓库),那么输出将会像是这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cd grit
$ git remote -v
bakkdoor https://github.com/bakkdoor/grit (fetch)
bakkdoor https://github.com/bakkdoor/grit (push)
cho45 https://github.com/cho45/grit (fetch)
cho45 https://github.com/cho45/grit (push)
defunkt https://github.com/defunkt/grit (fetch)
defunkt https://github.com/defunkt/grit (push)
koke git://github.com/koke/grit.git (fetch)
koke git://github.com/koke/grit.git (push)
origin git@github.com:mojombo/grit.git (fetch)
origin git@github.com:mojombo/grit.git (push)
我们可以拉取任何一个用户的贡献。
添加远程仓库
运行 git remote add <shortname> <url>
添加一个远程仓库,同时指定一个简写:
1
2
3
4
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit $ git remote -v
origin https://github.com/schacon/ticgit (fetch) origin https://github.com/schacon/ticgit (push) pb https://github.com/paulboone/ticgit (fetch) pb https://github.com/paulboone/ticgit (push)
以后就可以使用 pb
来代替整个 URL。如想要拉取 paulboone 的仓库,只需要输入:
1
2
3
4
5
6
7
8
$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
* [new branch] master -> pb/master
* [new branch] ticgit -> pb/ticgit
然后就可以在本地通过 pb/master
访问到了。
从远程仓库中抓取与拉取
如上面所见,从远程仓库中获得数据,可以执行 git fetch [remote-name]
命令。这个命令会访问远程仓库,拉取本地没有的数据。执行完成后,可以随时合并或查看。
如果是使用 git clone
命令克隆了一个仓库,命令会自动将其添加为远程仓库并以 origin
为简写。所以 git fetch origin
会抓取 git clone
后(或上一次 git fetch
后新推送的所有工作。
需要注意的是 git fetch
命令只会将数据拉取到本地,但是不会自动合并或修改当前分支,需要你自己准备好的时候手动合并。
如果你需要从默认远程分支上抓取并合并,可以使用 git pull
命令。该命令自动抓取默认的远程仓库分支,并尝试合并到当前本地分支。一般情况下,git clone
命令会自动设置本地 master
分支跟踪并克隆远程仓库的 master
分支(或其他名字的默认分支)。
推送到远程仓库
当你想要分享项目时,必须将其推送到上游,使用 git push [remote-name] [branch-name]
命令来操作。比如当你想要将本地的 master
分支推送到远程 origin
服务器时(这一般是克隆时命令自动设置的远程服务器名字),那么运行如下代码:
1
$ git push origin master
只有你拥有远程仓库的写入权限,并且之前没有人推送过时,该命令才能生效。如果在你克隆后,其他人先推送了项目到上游,此时你需要先将他们的工作拉取下来并合并到你的工作后,才能推送成功。
查看远程仓库
如果想要查看远程仓库的更多信息,可以使用 git remote show [remote-name]
命令。如查看 origin
:
1
2
3
4
5
6
7
8
9
10
11
12
$ git remote show origin
* remote origin
Fetch URL: https://github.com/schacon/ticgit
Push URL: https://github.com/schacon/ticgit
HEAD branch: master
Remote branches:
master tracked
dev-branch 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)
该命令会列出远程仓库的 URL 和跟踪分支的信息。该输出表示你正处于 master
分支(HEAD branch: master
),并且如果你运行 git pull
,就会抓取所有远程引用,然后将远程 master
分支合并到本地 master
分支(master merges with remote master
)。
如果是 Git 的重度使用着,将会通过 git remote show
看到更多信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ git remote show origin
* remote origin
URL: https://github.com/my-org/complex-project
Fetch URL: https://github.com/my-org/complex-project
Push URL: https://github.com/my-org/complex-project
HEAD branch: master
Remote branches:
master tracked
dev-branch tracked
markdown-strip tracked
issue-43 new (next fetch will store in remotes/origin)
issue-45 new (next fetch will store in remotes/origin)
refs/remotes/origin/issue-11 stale (use 'git remote prune' to remove)
Local branches configured for 'git pull':
dev-branch merges with remote dev-branch
master merges with remote master
Local refs configured for 'git push':
dev-branch pushes to dev-branch (up to date)
markdown-strip pushes to markdown-strip (up to date)
master pushes to master (up to date)
这里输出显示了当你在特定分支上执行 git push
时会将本地项目推送到哪个远程分支,还列出了哪些分支不在本地,哪些远程分支已经从服务器删除,还有当你执行 git pull
时哪些分支会自动合并。
远程仓库的移除与重命名
重命名远程引用,可以通过 git remote rename
修改。例如将上面的 pb
重命名为 paul
可以通过下面命令实现: bash $ git remote rename pb paul $ git remote origin paul
需要注意的是这也同样会修改远程分支中的名字,那些之前引用 pb/master
的现在会引用 paul/master
。
如果需要移除一个远程仓库,可以使用 git remote rm
命令: bash $ git remote rm paul $ git remote roigin
打标签
列出标签
使用 git tag
命令列出标签: bash $ git tag v0.1 v1.3
该命令默认以字幕顺序列出标签。
你也可以使用特定的模式查找标签,如查看 Git 自身源代码仓库的 1.8.5 系列,可以运行:
1
2
3
4
5
6
7
8
9
10
11
$ git tag -l 'v1.8.5*'
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5
创建标签
Git 使用轻量标签(lightweight)与附注标签(annotated)两种标签。
轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用。
附注标签是存储在 Git 数据库中的一个完整对象。他们是可以被校验的,包括:打标签者的名字、电子邮件地址、日期时间、标签信息,并且可以使用 GNU Privace Guard(GPG)签名与验证。通常建议创建附注标签,这样就可以拥有以上所有信息;但如果想要临时标签,或者不想保存这些信息,轻量标签也是可以的。
附注标签
在运行 git tag
时指定 -a
选项,来创建一个附注标签:
1
2
3
$ git tag -a v1.4 -m 'my version 1.4'
$ git tag
v1.4
-a
选项指定了一条需要存储在标签中的信息,如果没有指定信息,Git 会通过运行编辑器来要求你输入信息。
通过使用 git show
命令可以看到标签信息和对应的提交信息:
1
2
3
4
5
6
7
8
9
10
11
$ git show v1.4
Tagger: Ben Straub <ben@straub.cc>
Date: Sat May 3 20:19:12 2014 -0700
my version 1.4
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
轻量标签
轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。创建轻量标签只需要提供标签名字: bash $ git tag v1.4-lw $ git tag v1.4 v1.4-lw
这是如果在标签上运行 git show
将不会看到额外的信息。命令只显示提交信息:
1
2
3
4
5
6
$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
后期打标签
通过指定提交的校验和,来对历史提交进行打标签。
比如一个这样的提交历史:
1
2
3
4
5
$ git log --pretty-oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
假设在 v1.2 时忘记打标签,也就是在 updated rakefile
提交,可以在命令末尾添加校验和(或部分校验和): bash $ git tag -a v1.2 9fceb02
通过 git show v1.2
可以看到已经打上了标签:
1
2
3
4
5
6
7
8
9
10
11
$ git show v1.2
tag v1.2
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 15:32:16 2009 -0800
version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <mchacon@gee-mail.com>
Date: Sun Apr 27 20:43:35 2008 -0700
updated rakefile
共享标签
默认情况下 git push
命令不会推送标签到远程服务器。可以显式的将标签推送到共享服务器:
1
2
3
4
5
6
7
8
$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag] v1.5 -> v1.5
如果需要一次推送多个标签,可以使用带有 --tags
选项的 git push
命令。这将会把所有不在远程仓库服务器上的标签全部推送过去。
1
2
3
4
5
6
7
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag] v1.4 -> v1.4
* [new tag] v1.4-lw -> v1.4-lw
检出标签
在 Git 中并不能真正的检出一个标签。因为标签不能像分支一样来回移动。如果需要工作目录与仓库中特定的标签版本完全一样,可以使用 git checkout -b [branchname] [tagname]
在特定的标签上创建一个新分支:
1
2
$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'
当然,如果在这之后又进行了一次提交,version2
分支会因为改动向前移动,那么 version2
分支就和 v2.0.0
标签有些不同了。
Git 别名
Git 并不会在你输入部分命令时自动推断你想要的命令。如果不想每次输入完整的 Git 命令,可以通过 git config
文件来为每个命令设置一个别名。比如:
1
$ git config --global alias.br branch
这意味着,当你需要输入 git commit
命令时,只需要输入 git ci
。