本文引用参考文档地址
# GIT
本手册主要以操作命令的说明为主,力求包含大部分常用命令,适合初级使用者阅读。由于GIT本身命令繁多、过于灵活的原因,很多使用者对一些命令容易混肴,所以本文在讲解命令时,加入一些底层原理的说明,以使读者能清晰概念、熟练使用。
# 一、Git配置
# 1.1 查看配置
- 查看现在的git环境详细配置
git config -l
- 查看不同级别的配置文件
#查看系统config
git config --system --list
#查看当前用户(global)配置
git config --global --list
#查看当前仓库配置信息
git config --local --list
2
3
4
5
6
7
8
配置文件位置
--system
系统级:(windows) <GIT安装目录>\Git\mingw64\etc\gitconfig
,(linux) /etc/gitconfig
--global
用户级:(windows) <用户目录>\.gitconfig
,(linux)~/.gitconfig
--local
仓库级:<项目目录>\.git\config
注意:对于同一配置项,三个配置文件的优先级是system < global < local
# 1.2 设置用户名与邮箱
设置用户名称和
Git
提交都会使用该信息,它被永远的嵌入到了提交中。
git config --global user.name "XXX" #名称
git config --global user.email XXX@XXX.com #邮箱
2
注意:--global
为全局配置,不加为某个项目的特定配置。
# 二、获得GIT仓库
# 2.1 创建本地仓库
创建全新仓库,在项目的根目录执行指令,会在项目目录产生
.git
目录
# 在当前目录新建一个Git代码库
git init
2
创建和使用本地库完整示例
#1、创建目录
mkdir project7
#2、进入目录
cd project7
#3、初始化目录为git项目
git init
#4、创建md文件追加内容# project7(一级标题)
echo "# project7" >> README.md
#5、添加说明文件到暂存区
git add README.md
#6、提交到本地仓库并写日志
git commit -m "first commit"
#7、添加远程主机,主机名为origin 地址为https://git.xxx.com/xxx.git
git remote add origin https://git.xxx.com/xxx.git
#8、本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了,-u 参数指定一个默认主机
git push -u origin master
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 2.2 克隆远程仓库
将远程服务器上的仓库完全镜像一份至本地
# 克隆一个项目和它的整个代码历史(版本信息)
git clone [url]
2
原理:
# 三、GIT文件操作
# 3.1 查看文件状态
#查看指定文件状态
git status [filename]
#查看所有文件状态
git status
2
3
4
5
# 3.2 将未跟踪的文件添加到暂存区
# 添加指定文件到暂存区
git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
git add [dir]
# 添加当前目录的所有文件到暂存区
git add .
2
3
4
5
6
7
8
# 3.3 提交
# 3.3.1 提交暂存
通过add只是将文件或目录添加到了暂存区,使用commit可以实现将暂存区的文件提交到本地仓库。
# 提交暂存区到仓库区
git commit -m [message]
# 提交暂存区的指定文件到仓库区
git commit [file1] [file2] ... -m [message]
# 提交工作区自上次commit之后的变化,直接到仓库区,跳过了add,对新文件无效
git commit -a
# 提交时显示所有diff信息
git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新变化
git commit --amend [file1] [file2] ...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
原理:
# 3.3.2 修订提交
#修订提交
git commit --amend
2
原理:
# 3.3.3 撤销提交
撤销提交有两种方式:使用
HEAD
指针和使用commit id
在Git
中,有一个HEAD指针指向当前分支中最新的提交。当前版本,我们使用HEAD^
,那么再钱一个版本可以使用HEAD^^
,如果想回退到更早的提交,可以使用HEAD~n
。(也就是,HEAD^=HEAD~1
,HEAD^^=HEAD~2
)
# 撤销上一次的提交,原理就是放弃工作区和暂存区的改动,同时HEAD指针指向前一个commit对象
git reset --hard HEAD~1
git reset --hard HEAD^
git reset --hard 59cf933
2
3
4
原理:
注:git reset –-soft
和git reset --hard
的区别在于:–-soft
回退到某个版本,只回退了commit
的信息,不会恢复到index file一级。如果还要提交,直接commit
即可;-–hard
彻底回退到某个版本,本地的源码也会变为上一个版本的内容,撤销的commit
中所包含的更改被冲掉。
# 增加一条新的 `commit`,它的内容和倒数第二个 `commit` 是相反的,从而和倒数第二个 `commit` 相互抵消,达到撤销的效果。
git revert HEAD^
2
# 3.4 日志与历史
# 查看提交日志
git log
# 以图形化的方式显示提交历史的关系
git log --graph
# 显示1行
git log -1
# 一个提交一行显示
git log --oneline
# 显示所有更新记录,包括已经撤销的更新
git reflog
# 显示commit历史,以及每次commit发生变更的文件
git log --stat
# 显示指定文件相关的每一次diff
git log -p [file]
# 显示某次提交的元数据和内容变化
git show [commit]
# 显示某次提交发生变化的文件
git show --name-only [commit]
# 显示某次提交时,某个文件的内容
git show [commit]:[filename]
# 显示指定文件是什么人在什么时间修改过
git blame [file]
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
# 3.5 撤销修改
- 取消暂存(撤销add)
# 暂存区的目录树会被重写,被当前分支指向的目录树所替换,但是工作区不受影响。
git reset HEAD <file>
2
- 撤销工作区文件修改
# 用暂存区指定的文件替换工作区的文件。
git checkout -- <file>
2
- 撤销工作区修改和暂存的内容
# 用HEAD 指向的分支中的文件替换暂存区和以及工作区中的文件
git checkout HEAD <file>
2
# 3.6 删除文件
# 3.6.1 删除未跟踪文件
如果文件还是未跟踪状态,直接删除文件就可了,bash中使用rm可以删除文件。
# 3.6.2 删除暂存文件
# 从暂存区删除文件,工作区物理文件则不做出改变
git rm --cached <file>
# 不但从暂存区中删除,同时删除工作区物理文件
git rm <file>
2
3
4
5
# 3.7 查看文件修改后的差异
用
git status
只能查看对哪些文件做了改动,如果要看改动了什么,可以用:
# 查看文件修改后的差异
git diff <file>
# 比较暂存区的文件与之前本地仓库中已经提交过的文件差异
git diff --cached <file>
# 比较本地仓库中已经提交过的文件与工作空间中的文件差异
git diff HEAD <file>
# 显示分支之间的差异
git diff [first-branch]...[second-branch]
2
3
4
5
6
7
8
9
10
11
# 3.8 签出
# 检出branch分支。更新HEAD以指向branch分支,以及用branch指向的树更新暂存区和工作区。
git checkout branch
# 汇总显示工作区、暂存区与HEAD的差异。
git checkout
# 同上
git checkout HEAD
# 用暂存区中filename文件来覆盖工作区中的filename文件。相当于取消自上次执行git add filename以来(如果执行过)的本地修改。
git checkout -- filename
# 维持HEAD的指向不变。用branch所指向的提交中filename替换暂存区和工作区中相应的文件。注意会将暂存区和工作区中的filename文件直接覆盖。
git checkout branch -- filename
# 注意git checkout 命令后的参数为一个点(“.”)。这条命令最危险!会取消所有本地的 #修改(相对于暂存区)。相当于用暂存区的所有文件直接覆盖本地文件,不给用户任何确认的机会!
git checkout -- . 或写作 git checkout .
# 如果不加commit_id,那么git checkout -- file_name 表示恢复文件到本地版本库中最新的状态。
git checkout commit_id -- file_name
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3.9 忽略文件
- 当不想把某些文件纳入版本控制中,在主目录下建立
.gitignore
文件。- 该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。
- 如果文件曾经被 Git 记录过,那么
.gitignore
就对它们完全无效。
# 3.10 临时保存
将目前还不想提交的但是已经修改的内容进行保存至堆栈中,包括工作区和暂存区中的内容,后续可以在某个分支上恢复出堆栈中的内容。
# 将所有未提交的修改(工作区和暂存区)保存至堆栈中,用于后续恢复当前工作目录。
git stash
# 查看当前stash中的内容。
git stash list
# 查看堆栈中最新保存的stash和当前目录的差异。
git stash show
# 将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。堆栈中的内容会删除。
git stash pop
# 将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除。
git stash apply
# 从堆栈中移除某个指定的stash
git stash drop + 名称
# 清除堆栈中的所有内容。
git stash clear
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3.11 合并提交点
获取某一个分支的某一次提交,并作为一个新的提交引入到当前分支上。
git cherry-pick <commit-id>
# 中止cherry-pick
git cherry-pick --abort
2
3
4
# 四、GIT分支
# 4.1 新建分支
# 新建一个分支,但依然停留在当前分支
git branch [branch-name]
# 新建一个分支,并切换到该分支
git checkout -b [branch]
# 新建一个分支,指向指定commit
git branch [branch] [commit]
# 新建一个分支,与指定的远程分支建立追踪关系
git branch --track [branch] [remote-branch]
2
3
4
5
6
7
8
9
10
11
原理:
# 4.2 查看分支
# 列出所有本地分支
git branch
# 列出所有远程分支
git branch -r
# 列出所有本地分支和远程分支
git branch -a
# 查看本地分支和远程分支的映射关系
git branch -vv
2
3
4
5
6
7
8
9
10
11
# 4.3 切换分支
# 切换到指定分支,并更新工作区
git checkout [branch-name]
# 切换到上一个分支
git checkout -
2
3
4
5
原理:
- 切换到feature1分支。
- 在feature1上提交一次。
# 4.4 合并分支
# 合并指定分支到当前分支
git merge [branch]
# 合并指定分支到当前分支
git merge [branch]
# 取消合并
git merge --abort
2
3
4
5
6
7
8
合并原理:
从目标 commit
和当前 commit
(即 HEAD
所指向的 commit
)分叉的位置起,把目标 commit
的路径上的所有 commit
的内容一并应用到当前 commit
,然后自动生成一个新的 commit
。
例如下面这个图中:
HEAD
指向了 master
,所以如果这时执行:
git merge branch1
Git 会把 5
和 6
这两个 commit
的内容一并应用到 4
上,然后生成一个新的提交,并跳转到提交信息填写的界面:
merge
操作会帮你自动地填写简要的提交信息。在提交信息修改完成后(或者你打算不修改默认的提交信息),就可以退出这个界面,然后这次 merge
就算完成了。
# 4.5 删除分支
# 删除分支
git branch -d [branch-name]
# 强制删除分支
git branch -D [branch-name]
# 删除远程分支
git push origin --delete [branch-name]
git branch -dr [remote/branch]
2
3
4
5
6
7
8
9
原理:
# 4.6 建立追踪关系
# 建立追踪关系,在现有分支与指定的远程分支之间
git branch --set-upstream [branch] [remote-branch]
git push --set-upstream [origin] [remote-branch]
git push -u [origin] [remote-branch]
2
3
4
5
# 五、远程仓库
# 5.1 远程仓库url类型
- https 类型
https://xxx.com/xxx/xxxx.git
使用加密的网页访问通道读写仓库,使用用户名及密码进行鉴权。
- SSH类型
git@xxx.com/xxx/xxxx.git
使用加密通道读写仓库,无单次上传限制,需先设置 “账户 SSH 公钥”,完成配对验证。
- Git配置SSH key
- 生成秘钥
# 会在<用户目录>\.ssh目录下生成id_rsa和id_rsa.pub两个文件
ssh-keygen -t rsa -C "你的邮箱地址"
2
- 配置公钥
将id_rsa.pub里的内容拷贝到git网站里的添加公钥
中。
- 验证
# 以码云为例,验证设置是否可以连接
ssh -T git@gitee.com
2
# 5.2 常用操作指令
# 显示所有远程仓库
git remote -v
# 显示某个远程仓库的信息
git remote show [remote]
# 增加一个新的远程仓库,并命名
git remote add [shortname] [url]
# 取回远程仓库的变化,并与本地分支合并
git pull [remote] [branch]
# 上传本地指定分支到远程仓库
git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
git push [remote] --force
# 推送所有分支到远程仓库
git push [remote] --all
# 简单查看远程---所有仓库
git remote (只能查看远程仓库的名字)
# 查看单个仓库
git remote show [remote-branch-name]
# 新建远程仓库
git remote add [branchname] [url]
# 修改远程仓库
git remote rename [oldname] [newname]
# 删除远程仓库
git remote rm [remote-name]
# 获取远程仓库数据
git fetch [remote-name] (获取仓库所有更新,但不自动合并当前分支)
git pull (获取仓库所有更新,并自动合并到当前分支)
# 上传数据,如git push origin master
git push [remote-name] [branch]
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
# 5.2.1 git remote
为了便于管理,Git要求每个远程主机都必须指定一个主机名。
git remote
命令就用于管理主机名。默认主机名为origin。
# 不带选项的时候,git remote命令列出所有远程主机。
git remote
# 使用-v选项,可以参看远程主机的网址。
git remote -v
# 查看该主机的详细信息。
git remote show <主机名>
# 添加远程主机。
git remote add <主机名> <网址>
# 删除远程主机。
git remote rm <主机名>
# 远程主机改名
git remote rename <原主机名> <新主机名>
# 修改远程主机地址
get remote set-url [主机名] [地址]
# 查看主机网址
git remote get-url [主机名]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 5.2.2 git fetch
一旦远程主机的版本库有了更新(Git术语叫做commit),需要将这些更新取回本地,这时就要用到
git fetch
命令。
# 将远程主机的更新,全部取回本地
git fetch <远程主机名>
# 取回特定分支的更新
git fetch <远程主机名> <分支名>
2
3
4
5
示例:
- 取回
origin
主机的master
分支。
git fetch origin master
所取回的更新,在本地主机上要用"远程主机名/分支名"的形式读取。比如origin
主机的master
,就要用origin/master
读取。
- 查看分支情况
git branch -r
origin/master
git branch -a
* master
remotes/origin/master
2
3
4
5
6
上面命令表示,本地主机的当前分支是master
,远程分支是origin/master
。
- 取回远程主机的更新以后,可以在它的基础上,使用
git checkout
命令创建一个新的分支。
# 在origin/master的基础上,创建一个新分支
git checkout -b newBrach origin/master
2
- 本地分支上合并远程分支
# 在当前分支上,合并origin/master
git merge origin/master
# 在当前分支上,合并origin/master(变基)
git rebase origin/master
2
3
4
5
# 5.2.3 git pull
取回远程主机某个分支的更新,再与本地的指定分支合并。
# 合并需要采用merge模式
git pull <远程主机名> <远程分支名>:<本地分支名>
# 合并需要采用rebase模式
git pull --rebase <远程主机名> <远程分支名>:<本地分支名>
2
3
4
5
注:如果远程主机删除了某个分支,默认情况下,git pull
不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull
不知不觉删除了本地分支。
示例:**
- 取回
origin
主机的next
分支,与本地的master
分支合并,需要写成下面这样。
git pull origin next:master
- 如果远程分支是与当前分支合并,则冒号后面的部分可以省略
# 取回origin/next分支,再与当前分支合并
git pull origin next
# 等同于先做git fetch,再做git merge
git fetch origin
git merge origin/next
2
3
4
5
6
注:在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone
的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master
分支自动"追踪"origin/master
分支。
- 手动建立追踪关系使用:
git branch --set-upstream master origin/next
- 如果当前分支与远程分支存在追踪关系,
git pull
就可以省略远程分支名。
# 本地的当前分支自动与对应的origin主机"追踪分支"(remote-tracking branch)进行合并
git pull origin
2
- 如果当前分支只有一个追踪分支,连远程主机名都可以省略。
# 当前分支自动与唯一一个追踪分支进行合并
git pull
2
原理:
# 5.2.4 git push
git push
命令用于将本地分支的更新,推送到远程主机。它的格式与git pull
命令相仿。
git push <远程主机名> <本地分支名>:<远程分支名>
注意:
- 分支推送顺序的写法是<来源地>:<目的地>,所以
git pull
是<远程分支>:<本地分支>,而git push
是<本地分支>:<远程分支>。 - 如果省略远程分支名,则表示将本地分支推送与之存在"追踪关系"的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
- 在git的全局配置中,有一个push.default属性,其决定了git push操作的默认行为。push.default 有几个可选值:nothing, current, upstream, simple(默认), matching
- nothing - push操作无效,除非显式指定远程分支,例如git push origin develop
- current - push当前分支到远程同名分支,如果远程同名分支不存在则自动创建同名分支。
- upstream - push当前分支到它的upstream分支上(这一项其实用于经常从本地分支push/pull到同一远程仓库的情景,这种模式叫做central workflow)。
- simple(默认) - simple和upstream是相似的,只有一点不同,simple必须保证本地分支和它的远程 upstream分支同名,否则会拒绝push操作。只推送当前分支。
- matching - push所有本地和远程两端都存在的同名分支。推送所有有对应的远程分支的本地分支。
示例:
- 将本地的
master
分支推送到origin
主机的master
分支。如果后者不存在,则会被新建。
git push origin master
- 如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
# 删除origin主机的master分支
git push origin :master
# 等同于
git push origin --delete master
2
3
4
- 如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
# 将当前分支推送到origin主机的对应分支
git push origin
2
- 如果当前分支只有一个追踪分支,那么主机名都可以省略。
git push
- 如果当前分支与多个主机存在追踪关系,则可以使用
-u
选项指定一个默认主机,这样后面就可以不加任何参数使用git push
。
# 将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。
git push -u origin master
2
- 不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用
--all
选项。
# 将所有本地分支都推送到origin主机
git push --all origin
2
- 如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做
git pull
合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用--force
选项。
git push --force origin
**注:**使用--force
选项,结果导致远程主机上更新的版本被覆盖。除非你很确定要这样做,否则应该尽量避免使用--force
选项。
git push
不会推送标签(tag),除非使用--tags
选项。
git push origin --tags
原理解析:把 branch 上传到远端仓库
实质上,push
做的事是:把当前 branch
的位置(即它指向哪个 commit
)上传到远端仓库,并把它的路径上的 commit
s 一并上传。
例如,现在的本地仓库有一个 master
,它超前了远程仓库两个提交;另外还有一个新建的 branch
叫 feature1
,远程仓库还没有记载过它。具体大概像这样:
这时我执行 git push
,就会把 master
的最新位置更新到远端,并且把它的路径上的 5
6
两个 commit
s 上传:
git push
而如果这时候我再切到 feature1
去后再执行一次 push
,就会把 feature1
以及它的 commit
4
上传到远程仓库:
git checkout feature1
git push origin feature1
2
# 六、标签 tag
tag是git版本库的一个标记,指向某个commit的指针。
# 6.1 新建标签
# 在当前 commit 上创建标签
git tag <tagname>
# 创建带注释的标签,弹出编辑器输入注释
git tag -a <tagname>
# 指定提交节点创建分支
git tag <tagname> <commit>
# 创建指定注释的标签
git tag -a <tagname> -m '注释信息'
git tag -a -m '注释信息' <tagname>
# 创建带签名的标签
git tag -s <tagname>
git tag -u <keyid> <tagname>
# 强制打标签(不管命名冲突)
git tag <tagname> -f
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 6.2 查看标签
# 查看所有标签
git tag
git tag -l
git tag -n
# 查看tag 指向commit 的修改信息
git show <tagname>
git show <commit>
2
3
4
5
6
7
8
9
10
# 6.3 删除tag
# 删除本地tag
git tag -d <tagname>
# 删除远程tag
git push origin --delete tag <tagname>
# 删除本地和远程tag(通过推送空tag 到远程)
git tag -d <tagname>
git push origin :refs/tags/<tagname>
2
3
4
5
6
7
8
9
# 6.4 远程tag
# 推送tag 到远程
git push --tags
# 推送指定的tag 到远程
git push origin <tagname>
# 拉取远程tag
git fetch origin tag <tagname>
2
3
4
5
6
7
8
9