Git 简单指导


Git 是目前世界上最先进的分布式版本控制系统

版本控制系统

版本控制系统是任何能让你了解到一个文件的历史,以及它的发展过程的系统
这样,使用版本控制系统就可以让自己和他人协作的时候了解修改了什么,在什么时候修改等

集中式版本控制系统 / 分布式版本控制系统

集中式版本控制系统

集中式版本控制系统,版本库是集中存放在中央服务器,需要进行操作的时候,需要先从中央服务器获取最新版本到本地的电脑再进行操作,操作完毕需要把自己修改完的版本推送到中央服务器

1
2
3
缺点:
必须要进行联网才可以工作
对于网络的带宽和速度要求较高

分布式版本控制系统

分布式版本控制系统与集中式版本控制系统最大的区别是分布式版本控制系统根本没有“中央服务器”

  1. 每个人的电脑上都是一个完整的版本库
    这样工作的时候就不需要进行联网了,例如两个人都对同一个项目进行了修改,只需要把修改后的版本推送给对方就可以看到对方修改的内容(只是举例,很少这样操作)

  2. 分布式版本控制系统的安全性能也更高,因为完整的版本库都存在每个人的电脑,某一个人的电脑坏了,不影响整体,可以从任一个人的电脑是进行拷贝,如果是集中式版本控制系统的中央服务器要是出了问题,所有人都工作不了

  3. 分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已

Git 准备工作

1
2
3
git config --global user.name "Your Name"		//name
git config --global user.email "email@example.com" //email
ssh-keygen -t rsa -C "youremail@example.com" //SSH Key

SSH Key 存在电脑用户目录下的 .ssh ,id_rsa.pub(公钥)

创建版本库 repository

即仓库,一个目录,里面所有的文件都被 Git 管理,每个文件的修改、删除等任何操作 Git 都可以跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”

  1. 创建一个版本库

    1
    2
    mkdir gitTest  //创建文件夹
    cd gtiTest //切换到 gitLearn 目录
  2. 通过以下命令把这个目录变成 Git 管理的仓库

    1
    git init

Windows:
Windows 创建版本库

1
ls -ah

可以看到提示信息,多出了一个 . git 目录,这个目录是用来跟踪管理版本库的,切勿随意改动

把文件添加到版本库

要使用版本控制系统,文件要以纯文本方式编写文件,因为所有的版本控制系统,只能跟踪文本文件的改动,详细到哪一行修改了哪一个字,但是图片和视频等二进制文件,虽然也可以用版本控制系统管理,但是不能跟踪文件的变动,即到底改了什么,版本控制系统不知道

  1. 在目录下新建一个 wihieree.txt 文本
  2. 使用 git 把文件添加到仓库
    1
    2
    git add wihieree.txt
    git commit -m "add wihieree.txt"

提交修改
add:提出更改(把它们添加到暂存区)
commit:实际提交改动,执行完毕后改动提交到 HEAD ,但是还没到远端仓库

查看仓库当前状态

修改 wihieree.txt 文件,添加 Wihieree gogogo!! 后运行

1
git status

该命令是让我们查看当前仓库的状态:
status 查看仓库当前状态
由输出信息可以得知当前仓库的状态,wihieree.txt 被修改过,但是该修改还没有被提交
如果想进一步查看修改了什么就可以使用

1
git diff

查看仓库做过什么修改
从输出可以得知我们在第 1 行增加了一句 wihieree gogogo!!
提交修改和文件

1
2
git add wihieree.txt
git commit -m "wihieree gogogo!!"

log 查看日志

查看日志,可以让我们看到版本的历史记录,知道什么时候哪个版本作了什么修改

1
git log

查看日志 log
可以看到有 2 次提交,最新的一次 wihieree gogogogit add wihieree.txt
最早的一次是 add wihieree.txt Apr 2 09:39:01 2019
log
如果想了解本地仓库的历史记录

1
git log

可以添加一些参数来修改他的输出,从而得到自己想要的结果:

  1. 只看某一个人的提交记录

    1
    git log --author=bob
  2. 一个压缩后的每一条提交记录只占一行的输出

    1
    git log --pretty=oneline
  3. 通过 ASCII 艺术的树形结构来展示所有的分支, 每个分支都标示了他的名字和标签

    1
    git log --graph --oneline --decorate --all
  4. 看看哪些文件改变了

    1
    git log --name-status

更多参数参考

1
git log --help

版本退回

HEAD 表示当前版本,上一个版本是 HEAD^ ,上上个版本是 HEAD^^ ,上 20 个版本 HEAD~20 ,以此类推
退回上上个版本,再进行查看 wihieree.txt

1
2
git reset --hard HEAD^
cat wihieree.txt

版本退回
可以看到版本被退回, wihieree gogogo!! 不见了
若想退回最新的版本,可以回滚找到最新版本的 HEAD,例如我这里是 37c54

1
git reset --hard 37c54

这样就可以恢复到最新的版本
git reset 既可以回退版本,也可以把暂存区的修改回退到工作区
使用 git reflog 命令可以查看输入的每一条命令,这样就可以找到以前版本的 HEAD 使用上面的办法进行回退

1
git reflog

  • 当在工作区把某个文件修改错误,想丢弃工作区的修改时,使用

    1
    git checkout -- <file>
  • 如上修改错误还进行 git add 提交到了暂存区,想丢弃修改时,使用

    1
    2
    git reset HEAD <file>
    git checkout -- <file>

hard/mixed/soft

1
2
3
4
5
hard:回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换
mixed(默认):回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态
不影响原来本地文件(未提交的也不受影响)
soft: 回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区
不影响原来本地的文件(未提交的也不受影响)


Git 工作区、暂存区、版本库之间的关系如上图所示
如想进一步了解工作区、暂存区、版本库之间的关系可以点击此处
hard/mixed/soft 区别深解可以点击此处

删除文件

新建一个 test.txt ,并提交,然后对它进行删除

1
rm test.txt

再查看仓库状态

1
git status

这时候就会提示你哪些文件被删除了
查看哪些文件被删除
此时可以选择 继续删除文件 或者 从版本库里恢复最新版本的文件(以前版本的找不到,只可以恢复最新版本)

  1. 继续删除

    1
    git rm test.txt
  2. 删错了,想恢复

    1
    git checkout -- test.txt

远程仓库

远程仓库是 Git 的杀手锏之一

远程仓库实际应用

用一台电脑充当服务器,全天候开机,其他人都从这个服务器仓库克隆一份到自己本地的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交

Github 营运而生

GitHub 是通过 Git 进行版本控制的软件源代码托管服务,只需要注册一个 GitHub 账号,就可以免费获得 Git 远程仓库
!!该博客也是使用 Github 进行搭建
注册完账号,网上寻找添加 SSH Key 的教程,就可以把本地 Git 仓库传输到 Github 仓库
若有在不同的电脑上进行提交的需求,也可以把那台电脑的 SHH Key 添加到 Github,这样每台电脑都可以把本地 Git 仓库推送到 Github 仓库上

推送本地 Git 仓库到 Github 仓库

在 Github 网站上新建一个 repo ,再把本地 Git 仓库关联到 Github 仓库

1
git remote add origin git@server-name:path/repo-name.git

关联后,推送 master 分支的所有内容(第一次)

1
git push -u origin master

后续提交新内容

1
git push origin master

这就体现了分布式版本系统的好处,本地工作根本和远程库没关系,没有网络也可以工作,只要在有网络的时候推送到远程库就可以了

从远程库克隆

首先在 Github 新建一个 repo,300498-Stock-analysis
Github 新建 repo
克隆一个本地库 git clone

1
git clone git@github.com:WiyeeLu/300498-Stock-analysis.git

Git 支持多种协议,包括 https ,但是通过 ssh 支持的原生 git 协议速度最快

分支管理

分支可以理解为漫威的平行宇宙,我现在学 Java ,另一个平行宇宙的我在学 Python,这时的两个我互不干扰,不过在某个时间点,两个平行宇宙合并了,那时候的我就学会了 Java 又学会了 Python
分支是用来将特性开发绝缘开来的。在创建仓库的时候,master 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上
HEAD 严格来说不是指向提交,而是指向 master,master 才是指向提交的,所以 HEAD 指向的就是当前分支
分支

创建分支

创建 dev 分支

1
git checkout -b dev

使用 git branch 查看当前分支

1
2
3
E:\gitLearn>git branch
* dev
master

前面带有 * 号的表示当前分支
在 wihieree.txt 上加上一行 lalala dev
进行提交:

1
2
git add wihieree.txt
git commit -m "add branch dev"

若工作完成,切换回 master 分支

1
git checkout master

把 dev 分支的工作成果合并到 master 分支上

1
git merge dev

合并完成就可以删除 dev 分支

1
git branch -d dev

删除后可查看 branch

1
git branch

查看是否只剩 master 分支

解决冲突

当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成
从远程分支抓取最新的提交(更新你的本地仓库至最新改动)

1
git pull

建立本地分支与远程分支的连接

1
git branch --set-upstream dev origin/dev        //dev 为分支名

解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交
用 git log –graph 命令可以看到分支合并图

分支管理策略

Git 分支十分强大,在团队开发中应该充分应用。
合并分支时,加上 –no-ff 参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而 fast forward 合并就看不出来曾经做过合并

BUG 分支

修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场 git stash 一下,然后去修复 bug,修复后,再 git stash pop ,回到工作现场

Feature 分支

开发一个新feature,最好新建一个分支

1
git checkout -b feature-vulcan

如果要丢弃一个没有被合并过的分支,可以通过 git branch -D 强行删除

多人协作(推送)

查看远程库信息,使用

1
git remote -v

本地新建的分支如果不推送到远程,对其他人就是不可见的
从本地推送分支,使用 git push origin branch-name ,如果推送失败,先用 git pull 抓取远程的新提交;
在本地创建和远程分支对应的分支,使用 git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致
建立本地分支和远程分支的关联,使用 git branch –set-upstream branch-name origin/branch-name;
从远程抓取分支,使用 git pull,如果有冲突,要先处理冲突

Rebase

rebase 操作可以把本地未 push 的分叉提交历史整理成直线
rebase 的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比

标签管理

发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照
tag 就是一个让人容易记住的有意义的名字,它跟某个 commit 绑在一起

####新建标签
新建一个标签,默认为HEAD,也可以指定一个commit id

1
git tag <tagname>

指定标签信息

1
git tag -a <tagname> -m "blablabla..."

查看所有标签

1
git tag

替换本地改动

若操作失误,可以使用下面的命令替换掉本地改动

1
git checkout -- <filename>

此命令会使用 HEAD 中的最新内容替换掉你的工作目录中的文件
已添加到暂存区的改动以及新文件都不会受到影响

假如想丢弃在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将本地主分支指向它

1
2
git fetch origin
git reset --hard origin/master

Git 常用命令

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
mkdir		//创建新目录
git init //初始化一个 Git 仓库
git add <fileName> //提交修改,可提交多次,把文件添加到暂存区
git commit -m <message> //提交所有文件,把暂存区的所有内容提交到当前分支
git status //查看仓库当前的状态
git log //查看日志,什么时候修改了什么
cat <file> //查看文件内容
git reset --hard commit_id //可以在不同的版本间恢复
git reflog //查看命令历史,以便要回到未来的某一个版本
git diff HEAD -- wihieree.txt //查看工作区和版本库里面最新版本的区别
git checkout -- wihieree.txt //把 wihieree.txt 文件在工作区的修改全部撤销,即回到最近一次 git commit 或 git add 时的状态
git reset HEAD <file> //在 commit 之前,可以使用这个命令把暂存区的修改撤销掉,重新放回工作区
git rm <file> //删除一个文件
git checkout -- <file> //删错了文件,只要版本库里还有,就可以使用该命令恢复版本库里的最新版本
git remote add origin git@server-name:path/repo-name.git //把本地 Git 仓库关联到 Github 仓库
eg. git remote add origin git@github.com:WiyeeLu/Wens-Stock-analysis.git
git clone username@host:/path/to/repository //把 GitHub 仓库克隆到本地
git push -u origin master //推送 master 分支的所有内容(第一次)
git push origin master //后续提交新内容
git branch //查看分支
git branch <name> //创建分支
git checkout <name> //切换分支
git checkout -b <name> //创建 + 切换分支
git merge <name> //合并某分支到当前分支
git branch -d <name> //删除分支
git log --graph //查看分支合并图
git merge --no-ff -m "merge with no-ff" dev //用普通模式合并,合并后的历史有分支
git stash //把当前工作现场“存储”起来
git stash pop //回到工作现场
git remote -v //查看远程库信息
git push origin branch-name //从本地推送分支
git pull //抓取远程的新提交(更新你的本地仓库至最新改动)
git checkout -b branch-name origin/branch-name //本地创建和远程分支对应的分支
git branch --set-upstream branch-name origin/branch-name //建立本地分支和远程分支的关联
git rebase //可以把本地未 push 的分叉提交历史整理成直线
git tag <tagname> //用于新建一个标签,默认为HEAD,也可以指定一个commit id
git tag -a <tagname> -m "blablabla..." //可以指定标签信息
git tag //可以查看所有标签
git push origin <tagname> //可以推送一个本地标签
git push origin --tags //可以推送全部未推送过的本地标签
git tag -d <tagname> //可以删除一个本地标签
git push origin :refs/tags/<tagname> //可以删除一个远程标签

 Comments