本文最后更新于:2024年5月7日 下午
本文介绍git常用命令的使用方法。
Git
译为
分布式版本控制系统
,是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。
安装
- Linux
1 |
|
1 |
|
- Windows
在 https://git-scm.com/download/win 下载 gitbash 并安装即可
测试
- Linux
1 |
|
- Windows
1 |
|
Repository
译为
版本库
或仓库
,是git的核心概念,用于存放代码与各个版本的补丁信息和用户配置信息等。
Git 配置
1 |
|
Git 信息流
初次接触git的人需要对git信息流有一个初步的理解,掌握脉络之后就明白各个命令实在干什么了,主要流程如下图:
主要概念
- workspace(工作区):当前工作目录,它持有实际文件;
- inedex(暂存区):保存临时改动,workspace的文件改动后通过add命令添加到index;
- repository(仓库):git管理的本地仓库,index中确定需要的更改提交到仓库中,存放提交的修改与历史变动;
- HEAD:指向最后一次提交的结果,可以理解为每一次commit提交代码都会在git中产生一个节点,每个节点代表一个代码仓库的历史状态,我们可以在各个节点之间反复横跳,但是一个时刻只能在一个节点上,而标记我们在那个节点的就是HEAD,很像C语言中的指针;
- Remote(远程端):git的真正妙用在于有统一的服务器管理协同工作的多个开发人员的代码,因此我们经常需要把本地仓库的代码推送(push)到远端,或把远端的代码拉取(fetch/pull)或复制(clone)到本地。
主要命令
仓库管理
git init
Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令。
在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。
1 |
|
在现有文件夹下使用该命令,会在当前文件夹创建
.git
目录,该目录记录git相关管理信息。
1 |
|
会在当前文件夹下创建
test_dir
文件夹,并在其中创建.git
文件夹。
git clone
git clone 从现有 Git 仓库中拷贝项目。
1 |
|
repo
: 要克隆的远程仓库地址
branch
: 将要克隆的远程仓库分支名称,如果不设置该项参数则会克隆默认分支
directory
: 本地仓库文件夹名称,如果不设置该项参数则以仓库名称命名文件夹
- 协议配置
1 |
|
git clone 时,可以所用不同的协议,包括 ssh, git, https 等,其中最常用的是 ssh,因为速度较快,还可以配置公钥免输入密码。
git config
查看和配置git相关信息。
1 |
|
查看git配置信息
1 |
|
编辑配置文件(针对当前仓库)
1 |
|
编辑配置文件(针对系统上所有仓库)
1 |
|
配置提交代码时的用户信息
本地信息流管理
本地信息流主要涉及工作区(workspace)、暂存区(index)和版本库(repository)
git add
git add 命令可将该文件添加到暂存区。
1 |
|
添加一个或多个文件到暂存区。
1 |
|
添加指定目录到暂存区,包括子目录。
1 |
|
他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
1 |
|
git add --update的缩写,他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。
1 |
|
git add --all的缩写,是上面两个功能的合集。
注:个人建议慎用 git add -A
,需要明确地知道每步add操作提交了什么,切实管理自己的仓库。
git rm
git rm 命令用于从暂存区和工作区中删除文件(会删除本地文件)。
1 |
|
将文件
file
从暂存区和工作区中删除。
1 |
|
强制删除选项
-f
。用于删除之前修改过并且已经放到暂存区域的情况。
1 |
|
--cached
选项,可以把文件从暂存区域移除,但仍然保留在当前工作目录中,即从跟踪清单中删除。
git commit
将暂存区中的内容添加到本地仓库中。
1 |
|
将暂存区的内容提交到本地仓库;
此过程中必须附加
message
信息,提交后会在git中生成唯一的名称记录这一提交,可以在git log
命令中查看。
1 |
|
可以对部分文件进行提交。
1 |
|
-a
参数设置修改文件后不需要执行 git add 命令,直接来提交。
1 |
|
修改刚刚提交的注释信息
注:首次提交必须设置用户信息的名称和邮箱。
git show
显示某次 commit 的修改
1 |
|
git checkout
此命令用来放弃掉所有还没有提交(就是 git add 或 git commit)的修改:内容修改与整个文件删除。但是此命令不会删除掉刚新建的文件。因为刚新建的文件还没已有加入到 git 的管理系统中。
1 |
|
将缓存区的文件覆盖到工作区中,在文件名与分支名没有歧义时可以省略
--
。如果暂存区有该文件的提交,则从暂存区中抓取文件覆盖当前工作区的文件,否则从最近一次commit中抓取该文件并覆盖当前文件。
总之就是把该文件最近一次 add 或 commit 的副本抓来覆盖了工作区的文件。
1 |
|
这个操作很危险,会清除工作区中未添加到暂存区的改动,放弃所有的工作区文件修改。
1 |
|
用 HEAD 指向的 master 分支中的文件替换暂存区和以及工作区中的文件。
1 |
|
用 HEAD 指向的 master 分支中的所有文件替换暂存区和以及工作区中的文件。
注:checkout HEAD
是极具危险性的命令,它不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
1 |
|
将当前所在Head的工作区状态直接带到开辟的全新分支当中,用于清空之前所有提交记录。
切换到新分支时没有任何提交记录,所有现有工作区的文件都是全新的,在添加到暂存区并提交之后才有了第一次提交。
git reset
git reset 命令用于回退版本,可以指定退回某一次提交的版本。
1 |
|
--mixed
为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。
1
git reset HEAD # 取消之前 git add 添加过的缓存。
暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
实例:
1
2
3
$ git reset HEAD^ # 回退所有内容到上一个版本
$ git reset HEAD^ hello.php # 回退 hello.php 文件的版本到上一个版本
$ git reset 052e # 回退到指定版本
--soft
参数用于回退到某个版本:实例:
1
git reset --soft HEAD~3 # 回退上上上一个版本
--hard
参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交:
1
git reset --hard HEAD
实例:
1
2
3
$ git reset –hard HEAD~3 # 回退上上上一个版本
$ git reset –hard bae128 # 回退到某个版本回退点之前的所有信息。
$ git reset --hard origin/master # 将本地的状态回退到和远程的一样**注:**谨慎使用 –hard 参数,它会删除回退点之前的所有信息。
HEAD 说明
- HEAD 表示当前版本
- HEAD^ 上一个版本
- HEAD^^ 上上一个版本
- HEAD^^^ 上上上一个版本
- 以此类推…
可以使用 ~数字表示
- HEAD~0 表示当前版本
- HEAD~1 上一个版本
- HEAD^2 上上一个版本
- HEAD^3 上上上一个版本
- 以此类推…
git diff
比较文件在暂存区和工作区的差异,即显示已写入暂存区和已经被修改但尚未写入暂存区文件对区别。
1 |
|
显示暂存区和工作区的差异。
1 |
|
显示暂存区和上一次提交(commit)的差异。
1 |
|
显示两次提交之间的差异。
git mv
用于移动或重命名一个文件、目录或软连接。
1 |
|
在git中移动文件
-f
: 强制文件移动(如果已经存在该文件则会覆盖)
git status
查看仓库当前的状态,显示有变更的文件,用于查看在你上次提交之后是否有对文件进行再次修改。
1 |
|
详细显示工作区和暂存区的修改、提交状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
On branch master
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: B
new file: C
new file: D
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: C
modified: D
modified: E
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: D -> F
Untracked files:
(use "git add <file>..." to include in what will be committed)
A
1 |
|
简略输出状态结果。
1
2
3
4
5
6
7
A B
AD C
AM D
M E
D a.txt
R D -> F
?? A
- 符号说明
A(Added)
: 新添加到暂存区的文件M(Modified)
: 已经提交过并被修改的文件D(Deleted)
: 已经提交过并被直接删除的文件R(Renamed)
: 重命名的文件AD
: 已经提交到暂存区后被删除AM
: 已经提交到暂存区后被修改??(Untracked)
: 未追踪的文件
git stash
1 |
|
将所有未提交的修改(工作区和暂存区)保存至堆栈中,用于后续恢复当前工作目录。
1 |
|
作用等同于git stash,区别是可以加一些注释:
例如:
1
2
3
4
5
6
7
git stash的效果:
stash@{0}: WIP on master: b2f489c second
1
git stash save “test1”的效果:
stash@{0}: On master: test1
1 |
|
查看当前stash中的内容
1 |
|
将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。
注:该命令将堆栈中最近保存的内容删除(栈是先进后出)
1 |
|
将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除,也就说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。
可以使用git stash apply + stash名字(如stash@{1})指定恢复哪个stash到当前的工作目录。
1 |
|
从堆栈中移除某个指定的stash
1 |
|
清除堆栈中的所有 内容
1 |
|
查看堆栈中最新保存的stash和当前目录的差异。
例如:
1
2
3
$ git stash show
src/main/java/com/wy/StringTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
git stash show stash@{1}
查看指定的stash和当前目录差异。通过
git stash show -p
查看详细的不同:
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
$ git stash show -p
diff --git a/src/main/java/com/wy/CacheTest.java b/src/main/java/com/wy/CacheTest.java
index 6e90837..de0e47b 100644
--- a/src/main/java/com/wy/CacheTest.java
+++ b/src/main/java/com/wy/CacheTest.java
@@ -7,6 +7,6 @@ package com.wy;
*/
public class CacheTest {
public static void main(String[] args) {
- System.out.println("git stash test");
+ System.out.println("git stash test1");
}
}
diff --git a/src/main/java/com/wy/StringTest.java b/src/main/java/com/wy/StringTest.java
index a7e146c..711d63f 100644
--- a/src/main/java/com/wy/StringTest.java
+++ b/src/main/java/com/wy/StringTest.java
@@ -12,7 +12,7 @@ public class StringTest {
@Test
public void test1() {
- System.out.println("=================");
+ System.out.println("git stash test1");
System.out.println(Strings.isNullOrEmpty(""));//true
System.out.println(Strings.isNullOrEmpty(" "));//false
System.out.println(Strings.nullToEmpty(null));//""
1 |
|
从最新的stash创建分支。
git revert
通过创建一次新的
commit
来撤销一次commit
所做出的修改。这种撤销的方式是安全的,因为它并不修改commitm history
。
1 |
|
将会查出倒数第二次(即当前commit的往前一次)提交的修改,并创建一个新的提交,用于撤销当前提交的上一次
commit
。
历史记录管理
git log
查看历史提交记录。
1 |
|
显示提交记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git log
commit 5ac3ea4f50f0f558d8ba36ef7b713054c4cfee69 (HEAD -> master)
Author: vvd-from-xiaobing's-notebook <zywvvd@mail.ustc.edu.cn>
Date: Sat Aug 29 16:11:56 2020 +0800
save
commit 50f554063e4ca3502dfc318817522aee88863d62
Author: vvd-from-xiaobing's-notebook <zywvvd@mail.ustc.edu.cn>
Date: Sat Aug 29 15:56:13 2020 +0800
add-e
commit 3de3b277020322cd8f6991987fe38158d3fcdfea
Author: vvd-from-xiaobing's-notebook <zywvvd@mail.ustc.edu.cn>
Date: Sat Aug 29 15:36:23 2020 +0800
save
1 |
|
--oneline
: 简略显示提交记录日志
1
2
3
4
5
$ git log --oneline
5ac3ea4 (HEAD -> master) save
50f5540 add-e
3de3b27 save
9313997 save
1 |
|
--graph
: 查看历史中什么时候出现了分支、合并;
--reverse
: 正常上方显示最新的提交信息,该参数可以反向输出信息;
1 |
|
--author
: 只想查找指定用户的提交日志;
--since
--until
--until
--after
: 按照时间过滤信息实例:
1
git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
git blame
git blame用来追溯一个指定文件的历史修改记录。它能显示任何文件中每行最后一次修改的提交记录。 所以,如果你在代码中看到有一个bug,你可以使用 git blame 标注这个文件,查看哪一次提交引入了这行。
1 |
|
查看
file
文件的修改记录。
可以使用 -L 指定文件的行数范围:
1 |
|
远程信息流管理
git remote
用于在远程仓库的操作。
1 |
|
显示所有远程仓库。
实例:
1
2
3
4
5
$ git clone git@github.com:zywvvd/Python_Practise.git
$ cd Python_Practise
$ git remote -v
origin git@github.com:zywvvd/Python_Practise.git (fetch)
origin git@github.com:zywvvd/Python_Practise.git (push)origin 为远程地址的别名。
1 |
|
显示某个远程仓库的信息。
实例:
1
2
3
4
5
6
7
$ git remote show git@github.com:zywvvd/Python_Practise.git
* remote git@github.com:zywvvd/Python_Practise.git
Fetch URL: git@github.com:zywvvd/Python_Practise.git
Push URL: git@github.com:zywvvd/Python_Practise.git
HEAD branch: master
Local ref configured for 'git push':
master pushes to master (up to date)
1 |
|
添加远程版本库。
实例:
1
2
3
# 提交到 Github
$ git remote add origin git@github.com:zywvvd/Python_Practise.git
$ git push -u origin master
1 |
|
删除远程仓库。
1 |
|
修改仓库名。
git fetch
用于从远程获取代码库。
1 |
|
获取远程
remote
仓库的信息,取回到本地。
1 |
|
取回特定分支的更新,可以指定分支名。
实例:
1
git fetch origin master
1 |
|
拉取所有可见分支
git pull
从一个仓库或者本地的分支拉取并且整合代码。
1 |
|
git pull
相当于git fetch
跟着一个git merge FETCH_HEAD
。<repository>
是仓库的名字,<refspec>
是分支的名字。如果都不写,会有一个默认值。实例:
1
git pull origin master
拉取远程服务器
origin
的master
分支。
1
git pull --all
拉取远程所有可见分支
注:git pull = git fetch + git merge。
git push
用于将本地分支的更新,推送到远程主机。
1 |
|
分支推送顺序的写法是<来源地>:<目的地>,所以git pull是<远程分支>:<本地分支>,而git push是<本地分支>:<远程分支>。
1 |
|
将本地的master分支推送到origin主机的master分支,如果后者不存在,则会被新建。
1 |
|
如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
1 |
|
如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
1 |
|
如果当前分支只有一个追踪分支,那么主机名都可以省略。
注:不带任何参数的git push,默认只推送当前分支,这叫做simple方式。此外,还有一种matching方式,会推送所有有对应的远程分支的本地分支。Git 2.0版本之前,默认采用matching方法,现在改为默认采用simple方式。如果要修改这个设置,可以采用git config命令。
1 |
|
1 |
|
如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。
1 |
|
将所有本地分支都推送到origin主机。
1 |
|
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
1 |
|
如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用–force选项。
上面命令使用–force选项,结果导致在远程主机产生一个”非直进式”的合并(non-fast-forward merge)。除非你很确定要这样做,否则应该尽量避免使用–force选项。
分支管理
git branch
用于分支管理。
1 |
|
列出本地分支。
1 |
|
查看每一个分支的最后一次提交。
1--merged` 与 `--no-merged` 这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。 如果要查看哪些分支已经合并到当前分支,可以运行 `git branch --merged
1 |
|
列出远程分支。
1 |
|
列出本地和远程所有分支。
1 |
|
创建分支。
1 |
|
删除本地分支。
1 |
|
删除远程分支,删除后还需推送到服务器
git push origin:<branchname>
。
1 |
|
重命名本地分支。
git checkout
checkout 命令除了放弃掉所有还没有提交的修改外,还有切换分支的功能。
1 |
|
切换到指定分支。
1 |
|
创建分支并切换过去。
git merge
用于从指定的commit(s)合并到当前分支的操作,有以下两种用途:
- 用于git-pull中,来整合另一代码仓库中的变化(即:git pull = git fetch + git merge)
- 用于从一个分支到另一个分支的合并
1 |
|
将
commit
合并到当前分支。
1 |
|
该命令仅仅在合并后导致冲突时才使用。
git merge --abort
将会抛弃合并过程并且尝试重建合并前的状态。但是,当合并开始时如果存在未commit的文件,git merge --abort
在某些情况下将无法重现合并前的状态(特别是这些未commit的文件在合并的过程中将会被修改时)。
1 |
|
--commit
参数使得合并后产生一个合并结果的commit节点。该参数可以覆盖--no-commit
。
--no-commit
参数使得合并后,为了防止合并失败并不自动提交,能够给使用者一个机会在提交前审视和修改合并结果。
1 |
|
--edit
和-e
用于在成功合并、提交前调用编辑器来进一步编辑自动生成的合并信息。因此使用者能够进一步解释和判断合并的结果。
--no-edit
参数能够用于接受自动合并的信息(通常情况下并不鼓励这样做)。
1 |
|
--ff
是指fast-forward命令。当使用fast-forward模式进行合并时,将不会创造一个新的commit节点。默认情况下,git-merge
采用fast-forward模式。
1 |
|
除非当前HEAD节点已经up-to-date(更新指向到最新节点)或者能够使用fast-forward模式进行合并,否则的话将拒绝合并,并返回一个失败状态。
1 |
|
--log[=<n>]
将在合并提交时,除了含有分支名以外,还将含有最多n个被合并commit节点的日志信息。
--no-log
并不会列出该信息。
1 |
|
--stat
参数将会在合并结果的末端显示文件差异的状态。文件差异的状态也可以在git配置文件中的merge.stat配置。
相反,-n
,--no-stat
参数将不会显示该信息。
1 |
|
--squash
当一个合并发生时,从当前分支和对方分支的共同祖先节点之后的对方分支节点,一直到对方分支的顶部节点将会压缩在一起,使用者可以经过审视后进行提交,产生一个新的节点。
注: 该参数和--no-ff
冲突
1 |
|
-q / --quiet
: 静默操作,不显示合并进度信息;
-v / --verbose
: 显示详细的合并结果信息。
git rebase
1 |
|
将本地的多次提交合并为一个,以简化提交历史。本地有多个提交时,如果不进行这一步,在git rebase master时会多次解决冲突(最坏情况下,每一个提交都会相应解决一个冲突)
示例:
1
2
3
4
5
6
7
8
git checkout master
git pull
git checkout local
git rebase -i HEAD~2 //合并提交 --- 2表示合并两个
git rebase master---->解决冲突--->git rebase --continue
git checkout master
git merge local
git push
标签
git tag
给仓库历史中的某一个提交打上标签
1 |
|
给当前commit打上轻量标签
1
2
3
4
5
git log --oneline
49a021d (HEAD -> master) c
cf68aa3 d
5318a62 (tag: tag-test, dev) b added:
75c5c3e add-a
1 |
|
列出仓库中的tag列表
可以使用正则表达式选择感兴趣的标签
1
2
git tag -l "test*"
test-2
1 |
|
创建附注标签,通过使用
git show
命令可以看到标签信息和与之对应的提交信息:
1
2
3
4
5
6
7
8
9
10
$ git show test-2
commit 49a021da8afad6b33f41a21fce057040c8ae8f80 (HEAD -> master, tag: test-2)
Author: zywvvd <zywvvd@mail.ustc.edu.cn>
Date: Sat Oct 17 14:22:13 2020 +0800
c
diff --git a/c b/c
new file mode 100644
index 0000000..e69de29也可以为某个commit打标签:
1
git tag -a v1.2 9fceb02
1 |
|
推送标签,普通的
git push
并不会把本地的标签推送到远程,需要手动推送标签。
1 |
|
如果想要一次性推送很多标签,也可以使用带有
--tags
选项的git push
命令。 这将会把所有不在远程仓库服务器上的标签全部传送到那里。
1 |
|
删除掉你本地仓库上的标签。
1 |
|
删除远程标签
1 |
|
检出标签所在的commit,会处于“分离头指针(detached HEAD)”的状态。
git 选项
- -d --delete:删除
- -f --force:强制
- -m --move:移动或重命名
- -r --remote:远程
- -a --all:所有
参考资料:
- https://www.runoob.com/git/git-basic-operations.html
- https://www.jianshu.com/p/37f3a7e4a193
- https://blog.csdn.net/chaiyu2002/article/details/82120256
- https://www.cnblogs.com/djiankuo/p/6492533.html
- https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%A1%E7%90%86
- https://www.jianshu.com/p/58a166f24c81
- https://blog.csdn.net/stone_yw/article/details/80795669
- https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%89%93%E6%A0%87%E7%AD%BE
文章链接:
https://www.zywvvd.com/notes/tools/git/git-usage/git-usage/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付