Git

git config

配置 Git 的相关参数。

Git 一共有3个配置文件:

  • 1.仓库级的配置文件:在仓库的.git/.gitconfig,该配置文件只对所在的仓库有效。
  • 2.全局级的配置文件:Mac系统在~/.gitconfig,Windows系统在C:\Users\<用户名>\.gitconfig
  • 3.系统级的配置文件:在Git的安装目录下(Mac 系统下安装目录在/usr/local/git)的etc文件夹中的gitconfig
    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
    41
    42
    # 查看配置信息
    # --local:仓库级,--global:全局级,--system:系统级
    $ git config <--local | --global | --system> -l

    # 查看当前生效的配置信息
    $ git config -l

    # 编辑配置文件
    # --local:仓库级,--global:全局级,--system:系统级
    $ git config <--local | --global | --system> -e

    # 添加配置项
    # --local:仓库级,--global:全局级,--system:系统级
    $ git config <--local | --global | --system> --add <name> <value>

    # 获取配置项
    $ git config <--local | --global | --system> --get <name>

    # 删除配置项
    $ git config <--local | --global | --system> --unset <name>

    # 配置提交记录中的用户信息
    $ git config --global user.name "<用户名>"
    $ git config --global user.email "<邮箱地址>"

    # 更改Git缓存区的大小
    # 如果提交的内容较大,默认缓存较小,提交会失败
    # 缓存大小单位:B,例如:524288000(500MB)
    $ git config --global http.postBuffer <缓存大小>

    # 调用 git status/git diff 命令时以高亮或彩色方式显示改动状态
    $ git config --global color.ui true

    # 配置可以缓存密码,默认缓存时间15分钟
    $ git config --global credential.helper cache

    # 配置密码的缓存时间
    # 缓存时间单位:秒
    $ git config --global credential.helper 'cache --timeout=<缓存时间>'

    # 配置长期存储密码
    $ git config --global credential.helper store

git clone

从远程仓库克隆一个版本库到本地。

1
2
3
4
5
6
7
8
# 默认在当前目录下创建和版本库名相同的文件夹并下载版本到该文件夹下
$ git clone <远程仓库的网址>

# 指定本地仓库的目录
$ git clone <远程仓库的网址> <本地目录>

# -b 指定要克隆的分支,默认是master分支
$ git clone <远程仓库的网址> -b <分支名称> <本地目录>

git init

初始化项目所在目录,初始化后会在当前目录下出现一个名为 .git 的目录。

1
2
# 初始化本地仓库,在当前目录下生成 .git 文件夹
$ git init

git status

查看本地仓库的状态。

1
2
3
4
5
6
7
# 查看本地仓库的状态
$ git status

# 以简短模式查看本地仓库的状态
# 输出中有两栏,左栏指明了暂存区的状态,右栏指明了工作区的状态。
# 文件状态:A 新增,M 修改,D 删除,?? 未添加到Git中
$ git status -s

git remote

操作远程库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 列出已经存在的远程仓库
$ git remote

# 列出远程仓库的详细信息,在别名后面列出URL地址
$ git remote -v
$ git remote --verbose

# 添加远程仓库
$ git remote add <远程仓库的别名> <远程仓库的URL地址>

# 修改远程仓库的别名
$ git remote rename <原远程仓库的别名> <新的别名>

# 删除指定名称的远程仓库
$ git remote remove <远程仓库的别名>

# 修改远程仓库的 URL 地址
$ git remote set-url <远程仓库的别名> <新的远程仓库URL地址>

# 显示某个远程仓库的信息
$ git remote show [remote]

git branch

操作 Git 的分支命令。

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
41
42
43
44
45
# 列出本地的所有分支,当前所在分支以 "*" 标出
$ git branch

# 列出本地的所有分支并显示最后一次提交,当前所在分支以 "*" 标出
$ git branch -v

# 列出所有远程分支
$ git branch -r

# 列出所有本地分支和远程分支
$ git branch -a

# 创建新分支,新的分支基于上一次提交建立(新建一个分支,但依然停留在当前分支)
$ git branch <分支名>

# 新建一个分支,并切换到该分支
$ git checkout -b <分支名>

# 创建远程分支到本地
$ git brabch -b <分支名> origin/<分支名>

# 将当前分支绑定到远程origin/<分支名>分支
$ git branch -u origin/<分支名>

# 修改分支名称
# 如果不指定原分支名称则为当前所在分支
$ git branch -m [<原分支名称>] <新的分支名称>
# 强制修改分支名称(即使新分支已经存在)
$ git branch -M [<原分支名称>] <新的分支名称>

# 删除指定的本地分支
$ git branch -d <分支名称>

# 强制删除指定的本地分支
$ git branch -D <分支名称>

# 删除远程仓库分支
$ git branch origin :<分支名>
$ git push origin –delete <branch-name>

# 查看哪些分支已经合并到当前分支
$ git branch --merged

# 查看哪些分支未合并到当前分支
$ git branch --no-merged

git checkout

检出命令,用于创建、切换分支等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 切换到已存在的指定分支
$ git checkout <分支名称>

# 创建并切换到指定的分支,保留所有的提交记录
# 等同于 "git branch""git checkout" 两个命令合并
$ git checkout -b <分支名称>

# 创建并切换到指定的分支,删除所有的提交记录
$ git checkout --orphan <分支名称>

# 替换掉本地的改动,新增的文件和已经添加到暂存区的内容不受影响
$ git checkout <文件路径>

# 抛弃所有的修改内容
# 请务必记得 git checkout -- <file> 是一个危险的命令。
# 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。
# 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
$ git checkout -- <file>

git cherry-pick

把已经提交的记录合并到当前分支。

1
2
# 把已经提交的记录合并到当前分支(选择一个commit,合并进当前分支)
$ git cherry-pick <commit ID>

git add

把要提交的文件的信息添加到暂存区中。当使用git commit时,将依据暂存区中的内容来进行文件的提交。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 把指定的文件添加到暂存区中
$ git add <文件路径>
# 添加指定目录到暂存区,包括子目录
$ git add <dir>
# 添加指定文件到暂存区
$ git add <file1>

# 添加所有修改、已删除的文件到暂存区中
$ git add -u [<文件路径>]
$ git add --update [<文件路径>]

# 添加所有修改、已删除、新增的文件到暂存区中,省略 <文件路径> 即为当前目录
$ git add -A [<文件路径>]
$ git add --all [<文件路径>]

# 查看所有修改、已删除但没有提交的文件,进入一个子命令系统
$ git add -i [<文件路径>]
$ git add --interactive [<文件路径>]

# git add . 和 git add * 区别
# git add . 会把本地所有untrack的文件都加入暂存区,并且会根据.gitignore做过滤
# 但是git add * 会忽略.gitignore把任何文件都加入(实测并没有把.gitignore忽略的文件也加进去)

git commit

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 把暂存区中的文件提交到本地仓库,调用文本编辑器输入该次提交的描述信息
$ git commit

# 把暂存区中的文件提交到本地仓库中并添加描述信息
$ git commit -m "<提交的描述信息>"

# 提交暂存区的指定文件到本地仓库
$ git commit <file1> -m "<提交的描述信息>"

# 把所有修改、已删除的文件提交到本地仓库中
# 不包括未被版本库跟踪的文件,等同于先调用了"git add -u"
# 会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过"git add"步骤
# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a -m "<提交的描述信息>"

# 修改最近一次提交。有时候如果提交注释书写有误或者漏提文件,可以使用此命令。
$ git commit --amend

# 修改上次提交的描述信息(使用一次新的commit,替代上一次提交)
$ git commit --amend -m "<提交的描述信息>"

git fetch

从远程仓库获取最新的版本到本地的tmp分支上。
必须注意git fetch命令只会将数据下载到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。

1
2
3
4
5
# 将远程仓库所有分支的最新版本全部取回到本地
$ git fetch <远程仓库的别名>

# 将远程仓库指定分支的最新版本取回到本地
$ git fetch <远程主机名> <分支名>

git merge

合并分支。

1
2
3
4
5
6
7
8
9
# merge之前先拉一下远程仓库最新代码
$ git fetch origin

# 把指定的分支合并到当前所在的分支下
$ git merge <分支名>

# git一般使用"Fast forward"模式,在这种模式下,删除分支后,会丢掉分支信息
# 不使用Fast forward方式合并,采用这种方式合并可以看到合并记录(保留分支信息)
$ git merge --no-ff -m '<合并描述>' <分支名>

git diff

比较版本之间的差异。
image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 比较当前文件和暂存区中文件的差异,显示没有暂存起来的更改
$ git diff [fileName]

# 查看与版本库区别
$ git diff HEAD -- filename 

# 比较暂存区中的文件和上次提交时的差异(--staged和 --cached是同义词)
$ git diff --cached
$ git diff --staged

# 比较当前文件和上次提交时的差异
$ git diff HEAD

# 查看从指定的版本之后改动的内容
$ git diff <commit ID>

# 展示本地仓库中任意两个 commit 之间的文件变动
$ git diff <commit ID> <commit ID>

# 比较两个分支之间的差异
$ git diff <分支名称> <分支名称>

# 查看两个分支分开后各自的改动内容
$ git diff <分支名称>...<分支名称>

git pull

从远程仓库获取最新版本并合并到本地。
首先会执行 git fetch,然后执行 git merge,把获取的分支的 HEAD 合并到当前分支。

1
2
# 从远程仓库获取最新版本。
$ git pull

git push

把本地仓库的提交推送到远程仓库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 将本地分支的更新,推送到远程主机。强制推送 -f
$ git push

# 上传本地指定分支到远程仓库
$ git push origin <branch>

# 强行推送当前分支到远程仓库,即使有冲突
$ git push <remote> –force

# 推送所有分支到远程仓库
$ git push <remote> –all
# 把本地仓库的分支推送到远程仓库的指定分支
$ git push <远程仓库的别名> <本地分支名>:<远程分支名>

# 删除指定的远程仓库的分支
$ git push <远程仓库的别名> :<远程分支名>
$ git push <远程仓库的别名> --delete <远程分支名>

git log

显示提交的记录。

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
# 打印所有的提交记录
$ git log

# 查看提交日志,单行显示
$ git log --pretty=oneline
# 单行显示,并缩短commit id
$ git log --oneline

# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat

# 打印从第一次提交到指定的提交的记录
$ git log <commit ID>

# 打印指定数量的最新提交的记录
$ git log -<指定的数量>

# 显示每一次diff
$ git log -p

# 查看分支合并图
$ git log --graph

# 格式化输出历史记录
$ git log --pretty=format:"%h %s"

Git 用各种 placeholder 来决定各种显示内容,挑几个常用的显示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
%H: commit hash
%h: 缩短的commit hash
%T: tree hash
%t: 缩短的 tree hash
%P: parent hashes
%p: 缩短的 parent hashes
%an: 作者名字
%aN: mailmap的作者名
%ae: 作者邮箱
%ad: 日期 (--date= 制定的格式)
%ar: 日期, 相对格式(1 day ago)
%cn: 提交者名字
%ce: 提交者 email
%cd: 提交日期 (--date= 制定的格式)
%cr: 提交日期, 相对格式(1 day ago)
%d: ref名称
%s: commit信息标题
%b: commit信息内容
%n: 换行

统计代码

1、统计个人代码量(修改提交者姓名):

1
git log --author="lxy" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

2、贡献者数量统计:

1
git log --pretty='%aN' | sort -u | wc -l

3、查看排名前 5 的贡献者:

1
git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5

git reflog

1
2
# 获取执行过的命令
$ git reflog

git reset

reset命令把当前分支指向另一个位置,并且相应的变动工作区和暂存区。(还原提交记录)

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
# 将 HEAD 的指向改变,撤销到指定的提交记录,文件未修改
# 相当于调用 "git reset --mixed" 命令后又做了一次 "git add"
# 只改变提交点,暂存区和工作目录的内容都不改变
$ git reset --soft <commit ID>

# 改变提交点,同时改变暂存区的内容
$ git reset --mixed <commit ID>

# 重置暂存区,但文件不受影响
# 相当于将用 "git add" 命令更新到暂存区的内容撤出暂存区,可以指定文件
# 没有指定 commit ID 则默认为当前 HEAD
# -mixed 是不带参数时的默认参数
$ git reset [<文件路径>]
$ git reset --mixed [<文件路径>]

# 将 HEAD 的指向改变,撤销到指定的提交记录,文件未修改
$ git reset <commit ID>
$ git reset --mixed <commit ID>

# 回退到某个commit ID版本
# 将 HEAD 的指向改变,撤销到指定的提交记录,文件也修改了
# 暂存区、工作区的内容都会被修改到与提交点完全一致的状态
$ git reset --hard <commit ID>

# 让工作区回到上次提交时的状态
$ git reset –hard HEAD
# 回退到上一个版本(一个^退一个版本,多个可用 --hard HEAD~100)
$ git reset --hard HEAD^

# 撤回暂存区的文件修改到工作区
$ git reset HEAD file

git revert

生成一个新的提交来撤销某次提交,此次提交之前的所有提交都会被保留。

1
2
# 生成一个新的提交来撤销某次提交
$ git revert <commit ID>

git tag

操作标签的命令。

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
# 列出所有标签列表
$ git tag

# 添加标签(默认对当前版本)
$ git tag <标签名称>

# 对某一提交记录打标签
$ git tag <标签名> <commit_id>

# 添加带有描述信息的附注标签,可以指定之前的提交记录
$ git tag -a <标签名称> -m "<标签描述信息>" [<commit ID>]

# 切换到指定的标签
$ git checkout <标签名称>

# 查看标签的信息,输出显示了打标签者的信息、打标签的日期时间、附注信息,然后显示具体的提交信息。
$ git show <标签名称>

# 删除指定的本地标签
$ git tag -d <标签名称>

# 将指定的标签提交到远程仓库
$ git push <远程仓库的别名> <标签名称>

# 将本地所有的标签全部提交到远程仓库
$ git push <远程仓库的别名> –-tags

# 从远程仓库中删除标签
$ git push origin :refs/tags/<标签名>

git mv

重命名文件或者文件夹。

1
2
# 重命名指定的文件或者文件夹
$ git mv <源文件/文件夹> <目标文件/文件夹>

git rm

删除文件或者文件夹。

1
2
3
4
5
6
7
8
# 移除跟踪指定的文件,并从本地仓库的文件夹中删除
$ git rm <文件路径>

# 移除跟踪指定的文件夹,并从本地仓库的文件夹中删除
$ git rm -r <文件夹路径>

# 移除跟踪指定的文件,在本地仓库的文件夹中保留该文件
$ git rm --cached

git stash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 暂存当前修改
$ git stash

# 恢复最近的一次暂存
$ git stash apply

# 恢复暂存并删除暂存记录
$ git stash pop

# 查看暂存列表
$ git stash list

# 移除某次暂存
$ git stash drop <暂存名>(例:stash@{0})

# 清除暂存
$ git stash clear

git rebase

1