Git学习

对Git还停留在推送、克隆。

认真学习!!!

思维导图(原作者:jackfrued):https://github.com/jackfrued/git-tips/blob/master/assets/git.png

一、关于版本控制

版本控制系统(VCS):可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态。

本地版本控制系统

集中化的版本控制系统( Centralized Version Control Systems,简称 CVCS )


版本库是一个中央服务器,下载到本地、work之后再次推送回,需要联网

分布式版本控制系统( Distributed Version Control System,简称 DVCS )


本地电脑:本地仓库
中央服务器:中央仓库

二、Git简介

Linus花了两周时间用C写了Git

三、Git使用

安装 Git

官网:https://git-scm.com/

设置 Git Config

1
2
git config --global user.name "Your Name"
git config --global user.email "email@example.com"

git init 初始化新仓库

使用git init进行 Git 仓库初始化

1
2
空的Git仓库提示
Initialized empty Git repository in /learngit/.git/
1
2
存在的Git仓库重新初始化
Reinitialized existing Git repository in /studygit/.git/

当前目录下会多一个.git的目录,版本库-仓库-repository,可以理解为一个目录。
注意:所有的版本控制系统,只跟踪文本文件的改动。

git add 纳入版本控制

使用git add <file>将文件纳入版本控制
使用git add .将目录下所有的文件纳入版本控制
注意:没有任何提示,Unix 的哲学是“没有消息就是好消息”,说明添加成功。

git commit 提交更新

使用git commit -m "xxx message"把文件提交到仓库

1
2
3
4
5
[master (root-commit) 1bbbdd3] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt

一个文件改动,2行插入

备注:git commit只会把执行过git add <file>,也就是 stage 提交

git status 检查当前文件状态

使用git status来检查当前文件的状态

1
2
3
4
5
6
7
8
9
10
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")

readme.txt 文件被修改,但未提交
1
2
3
4
5
6
7
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: readme.txt

对 readme.txt 的修改将要提交
1
2
3
On branch master
nothing to commit, working tree clean
没有提交的修改,工作目录是干净的,也就是未对工作区进项变动。

git diff 比较修改内容

使用git diff <file>查看修改的具体内容

1
2
3
4
5
6
7
8
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.

git log 查看提交历史

使用git log查看提交历史

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
commit 90402be54135de237d476af541b871e8cfed060c (HEAD -> master)
Author: AshinWang <ashin.wang@qq.com>
Date: Tue Sep 17 17:04:39 2019 +0800

append GPL

commit a21a06ec4f78aa274866a046c7113a9a3c9a50cc
Author: AshinWang <ashin.wang@qq.com>
Date: Tue Sep 17 16:51:15 2019 +0800

add distributed

commit 1bbbdd3f6e45b827856fe5cad852b320139cbda9
Author: AshinWang <ashin.wang@qq.com>
Date: Tue Sep 17 16:06:03 2019 +0800

wrote a readme file

git log记录是按时间从近到远

使用git log --pretty=oneline 只查看版本号

1
2
3
90402be54135de237d476af541b871e8cfed060c (HEAD -> master) append GPL
a21a06ec4f78aa274866a046c7113a9a3c9a50cc add distributed
1bbbdd3f6e45b827856fe5cad852b320139cbda9 wrote a readme file

1bbbdd3f6e45b827856fe5cad852b320139cbda9是用SHA1计算出的十六进制版本号(commit id)

每提交一个新版本,Git就会把它们自动串成一条时间线,工具参考CSDN:几款常用的Git 图形化工具

git reset –hard HEAD^ 回退上个版本

使用git reset --hard HEAD^可回退上一个版本
HEAD表示当前版本,上个版本是HEAD^,上上个版本是HEAD^^,往上100个版本写100个^太麻烦,所以可以写成HEAD~100。

1
HEAD is now at a21a06e add distributed

使用git reset --hard 版本号(几位即可,一般前7位)到指定版本

git reflog 查看commit id

1
2
3
4
5
90402be (HEAD -> master) HEAD@{0}: reset: moving to 90402b
a21a06e HEAD@{1}: reset: moving to HEAD^
90402be (HEAD -> master) HEAD@{2}: commit: append GPL
a21a06e HEAD@{3}: commit: add distributed
1bbbdd3 HEAD@{4}: commit (initial): wrote a readme file

Working Directory 工作区和Repository 版本库

Git init 所在的文件夹

.git隐藏的目录就是版本库

.git中,stage 可以理解为暂存区,当我们使用.git add <file>时,将文件添加至 stage
git commit将 stage 提交至分支,例子为 master

当我们在 working directory 新增一个文件,使用git status

1
2
3
4
5
6
7
8
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)

test.txt

nothing added to commit but untracked files present (use "git add" to track)
Untracked files:未被跟踪的文件,没有添加到 stage

使用git add test.txt将文件添加至 stage 再次git status查看

1
2
3
4
5
6
7
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file: test.txt

可以看出新增文件提示,此时的 test.txt 被添加至 stage

使用git commit -m "understand how stage works"

1
2
3
[master 8f21641] understand how stage works
1 file changed, 1 insertion(+)
create mode 100644 test.txt

再次git status

1
2
3
On branch master
nothing to commit, working tree clean
没有什么可以提交,工作很轻松~

git checkout – 将工作区回到版本库记录

文件在工作区做了变动,但是未 git add <file> to stage
使用git checkout -- <file>,注意--,没有--就是切换分支

1
2
3
4
5
6
7
8
9
10
11
12
13
sh-3.2# cat readme.txt 
Git is a distributed version control system.
Git is free software distributed under the GPL.
sh-3.2# vi readme.txt
sh-3.2# cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.

this is a test~
sh-3.2# git checkout -- readme.txt
sh-3.2# cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.

git reset HEAD 暂存区撤销

当 file 提交至 stage,使用git reset HEAD <file>撤销暂存区记录,再使用git checkout -- <file>撤销工作区的变动

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
sh-3.2# cat readme.txt 
Git is a distributed version control system.
Git is free software distributed under the GPL.
sh-3.2# vi readme.txt
sh-3.2# cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
ssssssssssssss~~~~~~~~~
sh-3.2# git add readme.txt
sh-3.2# git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: readme.txt

sh-3.2# git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
sh-3.2# 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")
sh-3.2# git checkout -- readme.txt
sh-3.2# cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
sh-3.2# git status
On branch master
nothing to commit, working tree clean

删除文件

工作区rm <file>
版本库git rm <file>,使用后提交git commit -m "message"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sh-3.2# rm test.txt 
sh-3.2# git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

deleted: test.txt

no changes added to commit (use "git add" and/or "git commit -a")
sh-3.2# git rm test.txt
rm 'test.txt'
sh-3.2# git commit -m "remove test.txt"
[master b09723f] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt

误删,可使用git checkout -- <file>恢复

git checkout 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

四、远程仓库的使用

方法一 克隆远程仓库

  1. 创建仓库

  2. 克隆远程仓库git clone <REMOTE_URL> 有 https 和 ssh 两种方式,但 ssh 快,可以免密推拉。

  3. 配置本地的git配置信息

    1
    2
    git config --global user.name "你的名字或昵称"
    git config --global user.email "你的邮箱"
  4. 提交

    1
    2
    3
    git add . #将当前目录所有文件添加到git暂存区
    git commit -m "my first commit" #提交并备注提交信息
    git push origin master #将本地提交推送到远程仓库

方法二 本地仓库

  1. git init #git初始化

  2. git remote add origin #关联远程仓库

  3. git pull origin master #克隆远程仓库的目录

  4. 提交

    1
    2
    3
    git add . #将当前目录所有文件添加到git暂存区
    git commit -m "my first commit" #提交并备注提交信息
    git push origin master -f #-f为强制 #将本地提交推送到远程仓库

参考:https://gitee.com/help/articles/4122

SSH警告

第一次使用Git的clone或者push命令连接GitHub时,会得到

1
2
3
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?

五、分支管理

git checkout -b 创建分支

使用git checkout -b dev创建并切换dev分支 -b表示创建,checkout表示切换
Switched to a new branch 'dev'

使用git branch查看当前分支,*表示当前处于哪个分支

1
2
3
sh-3.2# git branch
* dev
master

git checkout 切换分支

1
2
sh-3.2# git checkout master
Switched to branch 'master'

git merge 合并分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sh-3.2# git merge dev
Updating b09723f..ccaa1b6
Fast-forward #快进模式,直接把 master 指向 dev
readme.txt | 2 ++
1 file changed, 2 insertions(+)
sh-3.2# git branch
dev
devv
* master
sh-3.2# cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.

This is dev Branch!

git branch -d 删除分支

1
2
3
4
sh-3.2# git branch -d dev
Deleted branch dev (was ccaa1b6).
sh-3.2# git branch
* master

git switch -b 创建分支

git switch 切换分支

合并冲突

同名文件出现的合并问题

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
sh-3.2# git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
sh-3.2# git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Unmerged paths:
(use "git add <file>..." to mark resolution)

both modified: readme.txt

no changes added to commit (use "git add" and/or "git commit -a")
sh-3.2# cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.

<<<<<<< HEAD
This is branch test!
=======
This is a branch test~~
>>>>>>> feature1

git log –graph 查看分支合并图

git log --graph --pretty=oneline --abbrev-commit

分支策略

通常Git会用Fast forward模式,在这种模式下,删除分支后,会丢掉分支信息。

禁用fast forward模式

加上--no-ff参数为普通模式合并。
git merge --no-ff -m "merge with no-ff" dev

git stash 存储状态

1
2
sh-3.2# git stash
Saved working directory and index state WIP on dev: 88857f2 test

git stash list 查看 stash 存储内容

1
2
3
sh-3.2# git stash list
stash@{0}: WIP on dev: 88857f2 test
sh-3.2#

git stash apply stash@{0} 恢复 stash

git stash drop 删除 stash

git stash pop 恢复 stash 再删除 stash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sh-3.2# git stash pop
On branch dev
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")
Dropped refs/stash@{0} (29c795bea03e6bbb5a593224b1ae17f3de415a60)
sh-3.2# git list
git: 'list' is not a git command. See 'git --help'.

The most similar commands are
bisect
rev-list

git cherry-pick 复制分支

git branch -D 强制删除分支

git remote 查看远程仓库

当克隆一个仓库到本地仓库时,默认名字origin

1
2
sh-3.2# git remote
origin

使用git remote -v 查看仓库远程地址

1
2
3
sh-3.2# git remote -v
origin git@gitee.com:AshinWang/***.git (fetch)
origin git@gitee.com:AshinWang/***.git (push)

若没有权限,查看不到 push 地址

git push origin 推送分支

git push origin master推送到远程 master 分支

git clone 克隆分支

git checkout -b dev origin/dev 创建远程 origin 的dev分支

git pull 拉下最新分支

git branch --set-upstream-to=origin/<branch> <branch-name>本地与远程关联

git rebase 分支整理

六、标签管理

git tag 创建标签

git tag 查看版本

git show 查看版本详情

git tag -d v1.0 删除标签

git push origin :refs/tags/ 删除远程标签

git push origin 推送标签版本

git push origin –tags 全部推送

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
sh-3.2# git tag v1.0
sh-3.2# git tag
v1.0
sh-3.2# git log --pretty=oneline --abbrev-commit
88857f2 (HEAD -> dev, tag: v1.0) test
ccaa1b6 branch test
b09723f remove test.txt
8f21641 understand how stage works
90402be append GPL
a21a06e add distributed
1bbbdd3 wrote a readme file
sh-3.2# git tag v0.9 ccaa1b6
sh-3.2# git tag
v0.9
v1.0
sh-3.2# git show v0.9
commit ccaa1b6dc48a1eedd10a52994e76e2f0b7b12f68 (tag: v0.9)
Author: AshinWang <137251937@qq.com>
Date: Wed Sep 18 12:23:20 2019 +0800

branch test

diff --git a/readme.txt b/readme.txt
index 8443d23..ccd84a5 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
+
+This is dev Branch!
sh-3.2# git tag -d v0.9
Deleted tag 'v0.9' (was ccaa1b6)

七、自定义 Git

--global git

配置文件在 .git/config

Git 配置

user.name git config --global user.name "Your Name"
user.email git config --global user.email "email@example.com"

让 Git 显示有颜色,更加醒目!
color.ui git config --global color.ui true

忽略文件提交

编写.gitignore文件,如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini

# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build

# My configurations:
db.ini
deploy_key_rsa

配置别名

如:使用st代替status
git config --global alias.st status