git常用操作

git常用操作

配置文件

--global 设置值的域范围是当前登录用户,存储在文件 `~/.gitconfig`
--system 设置值的域范围是全部登录用户,存储在文件 `/etc/gitconfig`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

[写入设置]

# 配置当前登录用户在使用Git时的姓名和联系方式
git config --global user.name <username>
git config --global user.email <email-address>

# 配置系统级别的命令别名,对所有用户有效
git config --system alias.co checkout

# 运行下面命令对文件进行编辑
git config -e --global # 将打开 ~/.gitconfig
git config -e --system # 将打开 /etc/gitconfig

[读取设置]
git config user.name

换行的问题

  • CRLF: Carriage-Return Line-Feed的缩写,意思是回车换行,即 \r\n
  • LF: Line-Feed的缩写,意思是换行,即 \n
  • CR: Carriage-Return的缩写,回车,即 \r

敲击回车键(Enter)时,操作系统会插入不可见的字符表示换行,不同的操作系统插入不同

  • Windows: 插入 \r\n 回车换行;
  • Linux\Unix: 插入 \n 换行;
  • MacOS: 插入 \r 回车;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# AutoCRLF
# 提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf true
# 提交时转换为LF,检出时不转换
git config --global core.autocrlf input # 我的选择
# 提交检出均不转换
git config --global core.autocrlf false

# SafeCRLF
# 拒绝提交包含混合换行符的文件
git config --global core.safecrlf true
# 允许提交包含混合换行符的文件
git config --global core.safecrlf false # 我的选择
# 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn

git init

1
2
3
git init  # 把当前目录创建为版本库
git init <filename> # 创建filename文件夹并初始化版本库
git init --bare <path.git> # 创建裸版本库

git diff

1
2
3
git diff			# 对比工作区与暂存区
git diff HEAD 或 master # 对比工作区与HEAD指向的提交或master分支末端
git diff --cached # 对比暂存区与HEAD提交

git log

1
2
3
git log --graph		# 显示当前分支上的所有提交
git log master | HEAD | ref/heads/masger # 显示指定的分支末端提交
git log --oneline # 每个提交用一行显示

git status

1
2
git status -s		# 精简显示
git status -b # 显示分支

git reflog

1
2
3
4
5
6
# 显示.git/logs/refs/heads/master中最后5行内容
# 改文件记录了master分支曾经指向的所有commit,可用于数据恢复
git reflog show master | head -5

# 使用reflog命令的前提是
git config core.logallrefupdates true # 非裸板本库默认就是true

git reset

1
2
3
4
5
6
7
# 用法一:带path参数,用commit上的文件,重置暂存区的文件
git reset [-q] [<commit>] [--] <paths>...

# 用法二:不带path参数
git reset --hard <commit> # 把HEAD和HEAD所在分支移动到commit,并用该commit的文件树覆盖`暂存区`和`工作区`
git reset --mixed <commit> # 把HEAD和HEAD所在分支移动到commit,并用该commit的文件树覆盖`暂存区`
git reset --soft <commit> # 仅把HEAD和HEAD所在分支移动到commit,不修改暂存区和工作区

git checkout

1
2
3
4
5
6
7
8
9
10
# 用法一:带path参数,从指定的commit或branch所在的commit取回文件,覆盖到暂存区和工作区
git checkout [-q] [<commit> | <branch>] [--] <paths>...
git checkout -- paths # 省略commit时,意为从暂存区取回文件到工作区
git checkout -- . 或 git checkout . # 用暂存区覆盖工作区的全部

# 用法二:参数为分支名称,改变HEAD的指向为新branch,同时覆盖暂存区和工作区
git checkout [<branch>] # 省略branch,则意为对比工作区和HEAD变化

# 用法三: 切换并创建新分支,新分支指向<start_point>提交
git checkout [-m] [[-b|--orphan] <new_branch>] [<start_point>]

git branch

1
2
3
4
5
6
7
8
9
10
11
# 显示本地分支列表
git branch
git branch -r # 显示远程分支
# 创建分支,在<start-commit>节点上创建分支
git branch <branchname> [<start-commit>]
# 删除分支
git branch -d <branchname> # 删除前检查分支是否已合并
git branch -D <branchname> # 强制删除分支
# 分支重命名
git branch -m <oldbarnch> <newbranch> # 修改前检查newbranch是否已存在
git branch -M <oldbarnch> <newbranch> # 强制重命名

git remote

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
# 显示已注册的远程版本库
git remote -v

# 注册远程版本库
git remote add <remote-name> <file:///path/to/repos/hello-user1.git>
# [remote "new-remote"]
# url = file:///path/to/repos/hello-user1.git
# fetch = +refs/heads/*:refs/remotes/new-remote/*

# 从指定的版本库获取
git fetch new-remote

# 修改远程版本库的地址
git remote set-url new-remote file:///path/to/repos/hello-user2.git # 或手动修改.git/config文件

# 修改远程版本库名称
$ git remote rename new-remote user2

# 删除已注册的远程版本库
git remote rm user2

# 显示远程分支
git branch -r


# 更新所有已注册的远程版本库
git remote update

git merge

1
2
3
4
5
6
7
8
9
10
11
git merge [options...] <commit|branch|tag>...

# 合并发生冲突时,暂存区中保存了冲突文件的所有版本,工作区包含了问文件的待解决版本
# 冲突发生,有两种处理方式
# 1. git reset 重置暂存区,放弃合并
# 2. 手动合并工作区的冲突文件,然后add commit

# 合并发生树冲突,需要使用`git rm`删除工作区和暂存区不需要的文件,然后add commit

# 冲突时,查看暂存区
git ls-files -s

git stash

1
2
git stash	# 保存暂存区和工作区的工作进度
git stash list # 查看已保存的进度列表

git tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!里程碑创建了就尽量不要修改 #!

# 查看全部里程碑
git tag
# 创建里程碑
git tag -m <msg> <tagname> [<commit>]
# 删除里程碑
git tag -d <tagname>

# 推送,里程碑默认不会推送到远程
git push origin <tagname> # 手动指明要推送的里程碑名字
git push origin refs/tags/* # 推送全部里程碑

# 拉取,远端里程碑已更新,普通拉取不会把更新的里程碑同步到本地

# 显示距离当前最近的版本号
git describe

文件归档

1
2
# git归档能够智能的处理.gitignore和.git文件夹
git archive --output filename.zip v_1.12.5 # 对tag指向的提交进行归档

git clone

1
2
3
4
5
6
7
8
9
10
11
# 用法一:克隆仓库到目录,目录包含完整的工作区、暂存区
git clone <repository> <directory>

# 用法二:生成裸板本库
git clone --bare <repository> <directory.git>

# 用法三:生成裸板本库,并对上游版本库进行注册
git clone --mirror <repository> <directory.git>

# 查看上游版本库的注册信息
git remote -v

push

1
2
3
4
5
6
7
8
# 推送本地分支到远程分支
git push [<remote-repos> [<refspec>]]

eg:
git push /repos/demo.git master:master

# 在远程版本库上创建新分支
git push <remote> <new_branch>

pull

1
2
3
4
5
# git pull = git fetch + git merge
git pull [<remote-repos> [<refspec>]]

# 选项
--no-commit 不自动提交为commit,合并后的结果放入暂存区

fetch

1
2
3
# 强制使用远程库所有引用替换到本地的origin空间中
git fetch origin +refs/heads/*:refs/remotes/origin/*

.git/config

1
2
3
4
5
6
7
...
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/* # fetch的默认行为
url = /path/to/my/workspace/demo # origin远程库的地址
[branch "master"]
remote = origin
merge = refs/heads/master

远程版本库

1
2
3
4
5
# ! 远程版本库 1. 禁止修复提交 2. 禁止非快进推送(禁止强制推送)

# 查看远程版本库的分支
git ls-remote /repos/demo.git
git ls-remote origin

禁止非快进推送

1
2
# 将版本库的参数receive.denyNonFastForwards设置为true可以禁止任何用户进行非快进式推送
git --git-dir=/path/to/repos/shared.git config receive.denyNonFastForwards true

杂项

1
2
3
4
5
6
7
8
9
10
11
12
13
# 没有修改,空白提交
git commit --allow-empty -m "empty commit"

# 对提交进行修补
# --amend 对末尾的提交进行修补,提交ID会改变,但不会产生新提交。可以不带-m,因为上一次提交有自己的提交说明
# --reset-author 对上一次提交的用户信息也进行覆盖
git commit --amend --allow-empty --reset-author

git clean # 删除本地多余的目录和文件

# 查看当前仓库的所有引用
git show-ref

克隆版本库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 用法1
# 将<repository>指向的版本库创建一个克隆到<directory>目录。
# 目录<directory>相当于克隆版本库的工作区,文件都会检出,版本库位于工作区下的.git目录中。
git clone <repository> <directory>

# 用法2
# 不包含工作区,只克隆出一个裸版本库,一般约定俗成裸版本库的目录名以.git为后缀
git clone --bare <repository> <directory.git>

# 用法3
# 克隆出来的裸版本库对上游版本库进行了注册
# 这样可以在裸版本库中使用`git fetch`命令和上游版本库进行持续同步
git clone --mirror <repository> <directory.git>

# bare仓库也可以通过对普通手动修改生成。
# 1. 删除工作区全部内容,只保留.git目录
# 2. git config --bool core.bare true
# 3. 查看配置 git --git-dir=/path/to/repos/demo.git config core.bare # true

# 用git init命令生成bare仓库
git init --bare <directory.git>

推送和拉取

1
2
3
4
# <remote-repos>是远程版本库的地址或名称
# <refspec>是引用表达式,暂时理解为引用即可
git push [<remote-repos> [<refspec>]]
git pull [<remote-repos> [<refspec>]]

对等工作区

不使用--bare或者--mirror创建出来的克隆包含工作区,这样就会产生两个包含工作区的版本库。这两个版本库是对等的。

因为对等版本库各有自己的工作区,所以对等版本库只能互相拉取(pull),默认不能运行推送操作(push)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看当前库的上游版本库(源版本库)信息
$ git remote -v
origin /path/to/my/workspace/demo (fetch)
origin /path/to/my/workspace/demo (push)

# 注册上游远程版本库的奥秘都在Git的配置文件中
$ cat /path/to/my/workspace/demo-backup/.git/config
...
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = /path/to/my/workspace/demo
[branch "master"]
remote = origin
merge = refs/heads/master

命令

1
2
3
4
5
6
# 空提交
git commit --allow-empty -m "sync test 1"
# 禁止非快进式推送
git --git-dir=/path/to/repos/shared.git config receive.denyNonFastForwards true
# 分支图
git log --graph --decorate --oneline --simplify-by-decoration --all
作者

Liu Jun

发布于

2022-07-12

更新于

2022-07-29

许可协议