git常用命令

记录 Git 的常用操作命令,方便日后查看。

配置

git 的配置文件位于 ~/.gitconifg(当前系统用户下)。修改配置的方式有如下 3 种。

命令配置

1.配置用户名

1
git config --global user.name [yourname]

2.配置邮箱

1
git config --global user.email [youremail]

3.查看配置信息

1
git config --list

vim 编辑器

1
2
# 使用此命令,会进入 vim 编辑器
git config -e --global

.gitconfig

直接进入到当前系统用户根目录下的 .gitconfig 配置文件中进行修改。

更多的可配置信息可以参考: git config docs

配置忽略文件

通过在项目根目录下创建 .gitignore 文件来配置定义 一些文件(夹) 不被提交到 远程仓库。比如,当前项目的一些测试代码文件、编辑器配置文件、npm 管理包 node_modules 等。

可以使用 touch .gitignore 命令来生成该文件。(windows 下,无法创建没有名字的文件,其会把 . 后的认作后缀名)。

.gitignore文件示例

1
2
3
4
5
6
test/
node_modules/
.git
.idea/
.vscode
.gitignore

基本操作

git init

初始化 git 仓库,在项目文件夹中打开 git bash,输入 git init 即可创建 git 仓库。

项目文件夹中会生成一个 .git 文件夹。里面创建有暂存区和本地仓库区。

1
git init

git status

查看当前项目中的文件状态,即做出了何种类型的修改(增、删、改),文件是否被追踪。

1
git status

git add

将文件添加至暂存区。

1
2
3
4
5
6
7
8
# 将指定文件添加至暂存区
git add [文件名]
# 将所有文件添加至暂存区
git add .
# or
git add -A
# or
git add --all

git commit

暂存区 中的文件提交至 本地仓库 区。

1
2
3
4
5
6
7
8
# 以行内提交信息的方式提交
git commit -m '提交时的辅助说明信息'

# 也可以不带 -m 参数,直接回车,此时会进入 vim 编辑器 ,在这里书写你此次提交的信息
git commit

# 使用一次新的commit , 替代上一次的提交,如果代码没有改变,则更新上一次的提交信息。
git commit --amend -m [message]

git log

查看提交日志。

1
2
3
4
5
6
7
8
# 查看当前head 及 以前的 日志
git log

# 查看简洁的日志,每条提交日志以一条的形式展示
git log --oneline

# 查看所有的提交日志
git reflog

git checkout

将文件从暂存区还原到工作区。

1
git checkout [文件名.xxx]

git reset

将指定版本项目从本地仓库区还原到工作区。

1
git reset --hard [版本号]

打标签

像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等)。

列出标签

Git 中列出已有的标签是非常简单直观的。 只需要输入 git tag

1
2
3
4
5
6
7
8
9
10
11
# 列出所有标签
$ git tag

v1.0
v2.0

# 按照指定模式列出标签
$ git tag -l 'v1.8.*'

v1.8.2
v1.8.4

新建标签

Git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。

一个轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用。

然而,附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。 通常建议创建附注标签,这样你可以拥有以上所有信息;但是如果你只是想用一个临时的标签,或者因为某些原因不想要保存那些信息,轻量标签也是可用的。

附注标签

Git 中创建一个附注标签是很简单的。 最简单的方式是当你在运行 tag 命令时指定 -a 选项:

1
2
3
4
5
$ git tag -a v1.4 -m 'my version 1.4'
$ git tag
v0.1
v1.3
v1.4

-m 选项指定了一条将会存储在标签中的信息。 如果没有为附注标签指定一条信息,Git 会运行 vim 编辑器要求你输入信息。

通过使用 git show 命令可以看到标签信息与对应的提交信息:

1
2
3
4
5
6
7
8
9
10
11
12
$ git show v1.4
tag 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

输出显示了打标签者的信息、打标签的日期时间、附注信息,然后显示具体的提交信息。

轻量标签

另一种给提交打标签的方式是使用轻量标签。 轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。 创建轻量标签,不需要使用 -a-s-m 选项,只需要提供标签名字:

1
2
3
4
5
6
7
$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5

这时,如果在标签上运行 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
6
7
8
9
10
11
$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme

现在,假设在 v1.2 时你忘记给项目打标签,也就是在 updated rakefile 提交。 你可以在之后补上标签。 要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和)。

1
$ git tag -a v1.2 9fceb02

可以看到你已经在那次提交上打上标签了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5

$ 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 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样 - 你可以运行 git push origin [tagname]

1
2
3
4
5
6
7
8
9
10
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
git push origin --tags

现在,当其他人从仓库中克隆或拉取,他们也能得到你的那些标签。

分支操作

git branch

查看当前项目中的所有分支,在当前分支的前面会有一个 *

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看本地分支列表,不包含远程分支
git branch

# 查看远程分支列表
git branch -r

# 查看所有分支列表,包含本地和远程分支
git branch --all

# or
git branch -a

# 删除分支,对于已经合并过的分支可以进行删除,删除的是本地分支
git branch -d [分支名]

批量删除分支

实际开发中,我们会根据需求号 feature/.* 或 问题号 iss/.* 进行分支的切换。一段时间后,你会发现本地的分支非常多,并且大多数都是经过迭代的老分支。是可以删除的。

那么,我们可以利用 git bash 配合 linux 命令做批量删除分支。

1
git branch | egrep 'iss/.*' | xargs git branch -D

以上命令表示:

1
2
3
4
1. git branch 列出本地所有分支
2. egrep 'iss/.*' 表示匹配这些分支字符传中以 `iss/` 开头的字符串(分支名)。
3. xargs git branch -D 将第二步生成的字符串当做参数传递给 git branch -D
4. 删除成功。

再教你一个反向匹配的例子:

1
git branch | egrep -v 'master|base/func|release/20200313' | xargs git branch -D

以上命令表示:

1
2
3
4
1. git branch 列出本地所有分支。
2. egrep -v 'master|base/func|release/20200313' 表示匹配非 master, base/func, release/20200313 的其他分支。
3. xargs git branch -D 将第二步生成的字符串当做参数传递给 git branch -D
4. 删除成功。

鼓掌!

git branch -vv

如果想要查看设置的所有跟踪分支,可以使用 git branch-vv 选项。 这会将所有的本地分支列出来并且包含更多的信息,如每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有。

1
2
3
4
5
$ git branch -vv
iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets
master 1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
testing 5ea463a trying something new

这里可以看到 iss53 分支正在跟踪 origin/iss53 并且 “ahead” 是 2,意味着本地有两个提交还没有推送到服务器上。 也能看到 master 分支正在跟踪 origin/master 分支并且是最新的。 接下来可以看到 serverfix 分支正在跟踪 teamone 服务器上的 server-fix-good 分支并且领先 3 落后 1,意味着服务器上有一次提交还没有合并入同时本地有三次提交还没有推送。 最后看到 testing 分支并没有跟踪任何远程分支。

需要重点注意的一点是这些数字的值来自于你从每个服务器上最后一次抓取的数据。 这个命令并没有连接服务器,它只会告诉你关于本地缓存的服务器数据。 如果想要统计最新的领先与落后数字,需要在运行此命令前抓取所有的远程仓库。 可以像这样做:git fetch --all; git branch -vv

git checkout

切换分支,可以从当前分支切换到指定分支上。

1
2
3
4
# 切换分支
git checkout [分支名]
# 创建新的分支,并切换到这个分支
git checkout -b [分支名]

注:当需要同步远程分支到本地仓库时,可以执行 git checkout -b [branch] [remotename]/[branch] 命令。将指定远程分支 [remotename]/[branch] 同步到本地仓库。

例:

1
2
3
# 需要同步远程分支 develop 到本地仓库

git checkout -b develop origin/develop

运行 git checkout -b [branch] [remotename]/[branch]。 这是一个十分常用的操作所以 Git 提供了 --track 快捷方式:

1
git checkout --track origin/serverfix

该操作表示,在本地创建 serverfix 分支,并跟踪远程分支 origin/serverfix。当执行 git pull 命令时,会自动更新 origin/serverfix 远程分支的代码到 serverfix 分支上。

git merge

将指定分支合并到当前分支。git内部使用的是指针操作原理。

1
git merge [分支名]

注:在执行合并操作前,你首先需要切换到 要合入 的分支上,然后再执行合并操作。

例:

你需要将 trunk 分支的代码合并到 develop 分支上,首先你需要切换到 develop 分支上。

1
git checkout develop

然后执行合并操作。

1
git merge trunk

此时,trunk 分支上的新代码就被合并到了 develop 分支上。

远程仓库

git clone

从远程仓库拷贝项目至本地。

1
git clone [远程仓库地址] [重命名项目名]

注意:
项目名称参数不提供时,会默认使用原项目名称。

git fetch

git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。
然而,有一个命令叫作 git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令。
如果有一个像之前章节中演示的设置好的跟踪分支,不管它是显式地设置还是通过 clonecheckout 命令为你创建的。
git pull 都会查找当前分支所跟踪的服务器与分支,从服务器上抓取数据然后尝试合并入那个远程分支。

由于 git pull 的魔法经常令人困惑所以通常单独显式地使用 fetchmerge 命令会更好一些。

git pull

更新远程仓库代码至本地。用于更新项目其他成员提交的代码。一般在 push 前,一定要先 pull

1
git pull [远程仓库地址/仓库别名] [分支名]

git push

将本地仓库中的代码提交至远程仓库。

1
git push [远程仓库地址/仓库别名] [分支名]

推送本地分支至远程仓库

1
2
3
4
git push --set-upstream <远程仓库地址/仓库别名> <分支名>

# 也可以使用简写形式
git push -u <远程仓库地址/仓库别名> <分支名>

删除远程分支

假设你已经通过远程分支做完所有的工作了 - 也就是说你和你的协作者已经完成了一个特性并且将其合并到了远程仓库的 master 分支(或任何其他稳定代码分支)。 可以运行带有 --delete 选项的 git push 命令来删除一个远程分支。 如果想要从服务器上删除 serverfix 分支,运行下面的命令:

1
2
3
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
- [deleted] serverfix

基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。

git remote

1
2
3
4
5
6
# 查看所有的仓库别名
git remote
# 新增仓库别名
git remote add [别名] [远程仓库地址]
# 删除仓库别名
git remote remove [别名]

SSH免密码登陆github配置

git 支持多种数据传输协议

例:

https协议:https://github.com/jquery/jquery.git

ssh协议:git@github.com:jquery/jquery.git

每次 push 或者 pull 代码,如果使用 https 协议,那么都需要输入用户名和密码进行身份的确认,非常麻烦。

github 为了账户的安全,需要对每一次 push 请求都要验证用户的身份,只有合法的用户才可以 push,使用 ssh协议,配置 ssh 免密码,可以做到免密码往 github 推送代码。

SSH 免密码登录配置命令

  • 创建 SSH Key:ssh-keygen -t rsa

  • 在文件路径 C:\用户\当前用户名\ 找到 .ssh 文件夹。

  • 文件夹中有两个文件:

1
2
私钥:id_rsa
公钥:id_rsa.pub
  • 在 github -> settings -> SSH and GPG keys 页面中,新创建 SSH key

  • 粘贴公钥 id_rsa.pub 内容到对应文本框中。

  • github 中新建仓库或者使用现在仓库,拿到 git@github.com:用户名/仓库名.git。

  • 此后,再次 SSH 方式与 github “通信”,不用输入密码确认身份了。