Git的详细使用说明

10/21/2021 git

git在日常开发的过程中,作为一个分布式版本控制工具,我们有必要了解他的详细使用说明;git的安装就不多说了,windows去官网下载安装程序安装即可,mac常用的则是通过homebrew安装brew install git,linux则是apt-get install git;安装后在命令行输入git验证即可;以下则为我整理收集的常用的命令:

推荐:Git Explorer (opens new window)

# git init

git init <name>   
e.g. git init 'gitdemo' 或者进入gitdemo 直接 git init 也行
含义:在本地初始化一个空的仓库,目录名为gitdemo
1
2
3

# git add

git add <file>     
e.g. git add readme.txt  
含义:将在仓库下新建一个readme.txt文件,添加到仓库;后来commit内容也就是add进去的.注意,可反复多次使用,添加多个文件;
1
2
3

# git commit

git commit -m <message>   
e.g. git commit -m "init and readme.txt"  
含义:将之前add到仓库的文件提交到本地仓库,其中 -m <message> 意思为给本次提交添加备注信息
1
2
3

为啥 add 和 commit 分开?因为一次 commit 可以 提交很多次 add 的文件; add 是把文件提交到暂存区,没add之前的则是工作区,commit则是提交到对应分支仓库; 正常操作可能每次修改之后必须add 然后再commit; 其实在IDEA编辑器里通用的显示则是没有 add 的文件显示 红色, add的显示 绿色 ,commit之后 显示白色,修改commit过的文件还没 commit 则显示 蓝色

# git status

git status

e.g.
gitdemo/ (master✗) $ git status                                                                    
On branch master
nothing added to commit but untracked files present (use "git add" to track)
gitdemo/ (master✗) $ vim readme.txt                                                           
gitdemo/ (master✗) $ git status                                                                    
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   readme.txt
no changes added to commit (use "git add" and/or "git commit -a")

含义:可以查看当前仓库的更改状态,第一次 git status 发现没有什么改变.经过 vim 修改 readme.txt之后,再次 git status 则可以发现 modified:   readme.txt 是经过修改的;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# git diff

git diff <file>

e.g.
git diff readme.txt

diff --git a/readme.txt b/readme.txt
index 9cc39d9..f33b9f4 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
-git 
+git
+first update 
(END)
按 q/Q 可以退出;

含义:git diff 这个命令可查看具体的修改内容;比如这里显示的是添加了 first update 这段话;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# git log

git log
git log --pretty=oneline  这个可以让信息输出在一行

e.g.
git log
commit 81c90109460e517650437755b9eb64ca2bbf179a (HEAD -> master)
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Thu Oct 21 10:22:43 2021 +0800

    second update

commit 539a6470e2f1b6bafb215632be0fa61e71615fc2
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Thu Oct 21 10:03:35 2021 +0800

    first update

commit 6a7e49a0fca8032e4bc037aa18e95faa950cb035
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Wed Oct 20 19:32:11 2021 +0800

    init and readme.txt


git log --pretty=oneline
81c90109460e517650437755b9eb64ca2bbf179a (HEAD -> master) second update
539a6470e2f1b6bafb215632be0fa61e71615fc2 first update
6a7e49a0fca8032e4bc037aa18e95faa950cb035 init and readme.txt

含义:我们在开发的过程中会不断的add and commit,如果我们想看提交的历史记录,则可以使用 git log 这个命令.
这种 hash 值就是commitid 也就是版本号
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

在开发中,我们可能因为某种原因需要版本会退,那么配合 git log 查看 commitid :

# git reset

git reset --hard HEAD

e.g.
git reset --hard HEAD^
HEAD is now at 539a647 first update

git log 
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Thu Oct 21 10:03:35 2021 +0800

    first update

commit 6a7e49a0fca8032e4bc037aa18e95faa950cb035
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Wed Oct 20 19:32:11 2021 +0800

    init and readme.txt

含义:通过 git reset --hard HEAD 可以把当前仓库还原成当前版本;
注意 HEAD 指的是当前最近一次提交的版本,HEAD^ 指的是上一个版本,HEAD^^ 指的是上俩个版本;
上100个版本 则可以写成 HEAD~100 ,
上面示例中我们通过 git reset --hard HEAD^ 将 版本还原到上一个版本,
通过 git log 可以看到 已经少了 second update commit的记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
git reset --hard commitid

e.g.
git reset --hard 81c90109460e517650437755b9eb64ca2bbf179a
HEAD is now at 81c9010 second update

git log
commit 81c90109460e517650437755b9eb64ca2bbf179a (HEAD -> master)
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Thu Oct 21 10:22:43 2021 +0800

    second update

commit 539a6470e2f1b6bafb215632be0fa61e71615fc2
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Thu Oct 21 10:03:35 2021 +0800

    first update

commit 6a7e49a0fca8032e4bc037aa18e95faa950cb035
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Wed Oct 20 19:32:11 2021 +0800

    init and readme.txt

含义:在上面通过 HEAD^ 已经将版本还原了,只要窗口还没关,我们还能找到 second update 这个commitid 
通过 git reset --hard commitid 又可以还原到 second update 这个版本;
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

# git reflog

git reflog

e.g.
git reflog
81c9010 (HEAD -> master) HEAD@{0}: reset: moving to 81c90109460e517650437755b9eb64ca2bbf179a
539a647 HEAD@{1}: reset: moving to HEAD^
81c9010 (HEAD -> master) HEAD@{2}: commit: second update
539a647 HEAD@{3}: commit: first update
6a7e49a HEAD@{4}: commit (initial): init and readme.txt
(END)

含义:查看命令历史,以便确定要回到未来的哪个版本
1
2
3
4
5
6
7
8
9
10
11
12

# git checkout

git checkout -- <file>

e.g.
vim readme.txt
添加了woshinibaba

git status 
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   readme.txt
no changes added to commit (use "git add" and/or "git commit -a")

git diff readme.txt
diff --git a/readme.txt b/readme.txt
index d601bdd..cfe876e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,3 +1,4 @@
 git
 first update
 second update
+woshinibaba
(END)

git checkout -- readme.txt

git status                                                                   
On branch master
nothing added to commit but untracked files present (use "git add" to track)

git diff readme.txt

含义:首先我们在readme.txt文件中书写了部分内容,后来发现不合适,我们通过 git status 发现 readme.txt 文件修改了,
通过 git diff readme.txt 我们发现 我们+woshinibaba 的内容,经过 git checkout -- readme.txt 后发现,刚更
改的内容还原了.
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

如果我们已经 上述的 错误内容修改已经add了,那么我们可以通过:

git reset HEAD <file>

e.g.
vim readme.txt
添加了woshinibaba

git add readme.txt

git status                                                                  
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   readme.txt

git reset HEAD readme.txt
Unstaged changes after reset:
M	readme.txt

git diff readme.txt
diff --git a/readme.txt b/readme.txt
index d601bdd..cfe876e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,3 +1,4 @@
 git
 first update
 second update
+woshinibaba
(END)

git checkout -- readme.txt

git status                                                                   
On branch master
nothing added to commit but untracked files present (use "git add" to track)

git diff readme.txt

 
含义:我们可以通过git reset HEAD <file>把 暂存区的修改撤销掉(unstage),重新放回工作区:
之后通过git checkout -- readme.txt 可以撤销工作区内容
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

# git rm

git rm <file>
git rm -f <file>

e.g.
git rm readme1.txt                                                          
error: the following file has changes staged in the index:
    readme1.txt
(use --cached to keep the file, or -f to force removal)

git rm -f readme1.txt                                                       
rm 'readme1.txt'

含义:我们可以通过 git rm <file> 来删除文件,当文件已经被 add 过,我们可以使用 git rm -f readme1.txt 来删除;
1
2
3
4
5
6
7
8
9
10
11
12
13

上述讲的其实是git的其中一种特性,它是一个分布式版本管理工具.

集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器.

集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊.

分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了.而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了.

在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机.因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已.

那么接下来我们讲讲“中央服务器仓库”:

一般我们可以使用github,gitlab,或者自建git服务器当作中央服务器.相关创建远程仓库这里就不一一细说;

比如我在gitee上创建一个gitdemo的仓库,目前它还是一个空仓库.

# git push

http协议: git remote add origin https://gitee.com/vision2best/gitdemo.git

ssh协议:  git remote add origin git@gitee.com:vision2best/gitdemo.git

git push -u origin master  

含义:使用对应的协议链接将本地仓库和远程仓库进行关联,关联一个远程库时必须给远程库指定一个名字,`origin`是默认习惯命名; 之后通过 git push -u origin master 将本地仓库推送到远程仓库;
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,
还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令.
1
2
3
4
5
6
7
8
9

# git remote

git remote -v

git remote rm <name>

e.g.
git remote -v                                                               
origin	git@gitee.com:vision2best/gitdemo.git (fetch)
origin	git@gitee.com:vision2best/gitdemo.git (push)

git remote rm origin  

git remote -v 

含义:先用git remote -v 查看远程库信息,之后 rm 掉远程库;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# git clone

git clone git@gitee.com:vision2best/gitdemo.git
 
含义:从远程仓库克隆一个仓库到本地;后面的地址可以是https的也可以是ssh的;
1
2
3
git checkout -b dev
等同于
git branch dev & git checkout dev
也等同于
git switch -c dev

切换分支
git checkout dev 等于 git switch master


含义:创建一个dev分支,并却换到dev分支;

git branch

含义:查看当前分支,git branch命令会列出所有分支,当前分支前面会标一个*号.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

我们在dev分支上对readme.txt 做出修改增加一行"dev update";之后切换到master分支:

# git merge

git merge dev   

git merge --no-ff -m "merge with no-ff" dev

e.g.
Updating 81c9010..7230667
Fast-forward
 readme.txt | 1 +
 1 file changed, 1 insertion(+)

含义:可以将 dev 分支上的改动 merge 到master上;
也可以加上 --no-ff 表示 不使用 Fast forward 模式; -m 代表 合并之后创建一次新的提交;

1
2
3
4
5
6
7
8
9
10
11
12
13

合并分支后,可以删除dev分支:

# git branch

git branch -d dev

e.g.
git branch -d dev                                                           
Deleted branch dev (was 7230667).

含义:删除dev分支;
1
2
3
4
5
6
7

可能在日常工作,我们会出现多个问题同时解决的问题,但是我们一个问题未解决完,又不能提交上去.那么可以:

# git stash

# git cherry-pick

git stash
e.g.
git stash
Saved working directory and index state WIP on master: 7230667 dev update
含义:可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:当使用 git stash 后 git status 会发现工作空间没有变更的了

git stash list
e.g.
git stash list
stash@{0}: WIP on master: 7230667 dev update
含义:查看stash列表;

git stash apply <stash@{0}>
git stash drop <stash@{0}>
含义:恢复刚才的stash,但stash内容不删除 ,使用drop进行删除

git stash pop <stash@{0}>
含义:恢复刚才的stash,同时删除stash内容

git cherry-pick <commit>
含义:在master分支上修复的bug,想要合并到当前dev分支,可以用 git cherry-pick <commit> 命令,把bug提交的修改“复制”到当前分支,避免重复劳动.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# git tag

git tag <tagname>
含义:可以打一个名字为name的新标签:


git tag <tagname> <commit>
含义:对commit id是f52c633,打上tag;

git tag
e.g.
git tag
v0.1
(END)
含义:查看所有标签;
1
2
3
4
5
6
7
8
9
10
11
12
13

# git show

git show <tagname>
e.g.
commit 72306671de3a81d15170adf009f6e8c0b698649f (HEAD -> master, tag: v0.1)
Author: 张璜 <zhuang@servyou.com.cn>
Date:   Thu Oct 21 13:10:57 2021 +0800

    dev update

diff --git a/readme.txt b/readme.txt
index d601bdd..b5f7955 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,3 +1,4 @@
 git
 first update
 second update
+dev update
(END)
含义:查看标签信息

git rebase
含义:rebase操作的特点:把分叉的提交历史“整理”成一条直线,看上去更直观.缺点是本地的分叉提交已经被修改过了.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# git pull

git pull
含义:从远程仓库更新到本地仓库;
1
2

附上git本地生成ssh key操作:

创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsaid_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:

ssh-keygen -t rsa -C "youremail@example.com"

你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码.

如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人.

之后可以在对应的Github 或者 Gitee 上添加Add SSH Key;在Key文本框里粘贴id_rsa.pub文件的内容既可.

# Git 全局设置:

git config --global user.name "vision2best"
git config --global user.email "vlsion@126.com"
1
2

一般在创建远程仓库时会有相应的同步操作指导.

以上内容参照廖雪峰老师Git教程 (opens new window)整理;如有误,请指正!

最后更新时间: 11/24/2022, 9:44:46 AM