git的故事

2019/08/01 CICD

git使用

1、git的故事

​ Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码,之后使用商业的版本控制系统BitKeeper,2005年的时候,Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!

集中式和分布式

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

​ 分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了,实际上,分布式也有一个类似于“中央服务器”的概念。

2、git的安装

​ 安装地址:https://git-scm.com/ 直接下载安装即可。

3、git 的使用

3.1、创建版本库

​ 版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

​ 创建命令:

$ git init 

​ 添加一个文件:

$ git add . (文件名称)

提交到本地仓库:

$ git commit -m "提交信息"

查看仓库的状态:

$ git status 

查看仓库的历史日志:

# git log 默认顺序是从最近到最远 
$ git log

3.2、版本管理

3.2.1、git 版本管理命令

git有很强的版本管理的概念,包括版本提交,前进,回退,比对,状态查看等等操作。

​ 查看当前仓库状态:

$ git status

​ 查看某个文件修改内容:

$ git diff 文件名称

​ 重置当前版本:(不仅可以做到回退,HEAD^ 代表上一个,也可以使用commitID 来选择重置当前版本)

git reset --hard HEAD^

查看提交号:(这个命令可以每一次执行的命令)

$ git reflog 

3.2.2、git 的工作区和暂存区

​ 工作区:我们现在作为仓库的那个目录就是工作区。

​ 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

git add命令相当于把文件的修改从工作区添加到暂存区。

git commit 命令相当于把文件从暂存区提交到版本库。

​ 理解了工作区,暂存区,版本库的概念之后,有一种场景就是我本地做了修改,但是我后悔了,不想提交了,可以使用

$ git checkout --file

​ 丢弃现在的修改,git会从最近的一次git add或者git commit找到并重置工作区的这个文件。

​ 如果是git add 之后想要回退则需要的命令是:

$ git reset HEAD file

​ 这个命令可以把暂存区的修改撤销,从新放回工作区,此时再配合git checkout --file,文件直接 重置为版本库最近一次的提交。

​ 如果提交到版本库,想要撤回呢,就使用git reset --hard HEAD^ 即可。

​ 如果想要删除一个版本库的文件,有两种方式,一种是提交删除,一种是git命令,因为git认为删除也是一种修改。

​ 提交删除:

$ rm file
$ git add .
$ git commit -m "删除"

​ git删除:

$ rm file
$ git rm file
$ git commit -m "删除"

3.3、远程仓库

​ 介绍git的时候就提过,git也有一个类似于“中央服务器”的概念,就是远程仓库,其实随便另一个人的仓库都是远程仓库。

​ 本地仓库如何关联到远程仓库:

$ git remote add origin git@github.com:用户名/项目.git

也可以通过克隆命令将远程仓库的项目克隆到本地仓库:

$ git clone xxx.git

本地仓库提交到远程仓库:

# 第一次推送 (关联操作)
$ git push -u origin master
# 之后的推送可以直接使用
$ git push origin master

3.4、git的分支管理

​ 看廖雪峰的git教程中举了一个很形象的例子,分支就类似于科幻电影里面的平行宇宙,一个宇宙中的你正在努力的学习git,另一个宇宙的你正在努力的学习svn,两者学习互不干扰,某一天,平行宇宙合并了,结果就是你既学会了git也学会了svn。

3.4.1、git中创建和合并分支

​ git有一个时间线的概念,每一个时间线其实就是一个分支,HEAD其实并非是指向了最新的提交,而是指向了分支,而每一个分支才真正的指向了提交,类似于下面的图:

​ 我们可以想到,master也好,dev也好就是一个指针,HEAD通过指向这个指针,而真正关联到具体的提交。

​ 为什么git分支提交,分支合并很快的原因就在这里,比如,dev合并到master分支,直接把master分支这个指针指向dev的地址,然后把HEAD指向改后的master即可。

​ 创建分支:

$ git branch dev

切换分支:

$ git checkout dev

创建并切换分支:

$ git checkout -b dev

git也提供了心得操作来完成切换分支动作

#创建并切换分支
git switch -c dev
#切换到master分支
git switch master

分支合并操作

# 合并某分支到当前分支
git merge <branch-name>

删除分支

git branch -d <branch-name>

3.4.2、解决冲突

​ 当两个分支同时改一个文件的一处地方的时候,就会发生冲突,大概报错如下

Automatic merge failed; fix conflicts and then commit the result.

这时候,我们必须手动解决冲突之后再进行提交。

git status 查看冲突文件和冲突信息

人工解决完冲突文件之后,再进行

git add . 
git commit -m ""

此时,合并继续完成。

位于master分支上,可以删除feature分支了。

3.4.3、git中的分支管理策略

​ 合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

加上参数 --nf-ff就可以了。

合并的时候大概命令如下

git merge --no-ff -m "合并信息" dev

此时,就会产生一个新的commit id,方便管理和回溯、

3.4.4、git中的暂存

​ 如果当前的工作没有完成,不想提交,但是又有一个紧急的更新要做,就可以使用git的暂存功能,将当前的改变存储

git stash
git stash list
git stash pop

3.4.5、远程操作

​ 查看远程库的信息

git remote
# 显示更详细的信息
git remove -v

推送分支

git push origin master
git push origin dev
# 本地分支和远程分支建立联系 
git branch --set-upstream origin master

本地创建和远程分支对应的分支

git checkout -b branch-name origin/branch-name

拉取远程更新

git pull 将远程合并到本地仓库

3.4.6、rebase

​ 多人在同一分支上协作的时候,容易出现冲突问题。一般我们仓库看到的历史都是曲线,像这样

git log --graph --pretty=oneline --abbrev-commit
* d1be385 (HEAD -> master, origin/master) init hello
*   e5e69f1 Merge branch 'dev'
|\  
| *   57c53ab (origin/dev, dev) fix env conflict
| |\  
| | * 7a5e5dd add env
| * | 7bd91f1 add new env
| |/  
* |   12a631b merged bug fix 101
|\ \  
| * | 4c805e2 fix bug 101
|/ /  
* |   e1e9c68 merge with no-ff
|\ \  
| |/  
| * f52c633 add merge
|/  
*   cf810e4 conflict fixed

其实可以把git 的提交变成一条执行,那就是git rebase命令,rebase命令会把我们本地的提交修改位置到应该到的位置,本地的修改想到与合并到后面的文件上去,这样提交就可以是直线了。

3.5、git中的标签

​ 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。

切换到打标签的分支上

# 查看当前分支
git branch 
# 打标签
git tag v1.0
#查看标签
git tag 

标签是打在最新的提交上的,如何打在历史提交上

git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file

比方说要对add merge这次提交打标签,它对应的commit id是f52c633,敲入命令:

$ git tag v0.9 f52c633

标签排序是按照字母排序的,有时间无关。

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

$ git tag -a v0.1 -m "version 0.1 released" 1094adb

标签删除

$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)

如果要推送某个标签到远程,使用命令git push origin <tagname>

# 标签推送
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v1.0 -> v1.0
 # 推送全部标签
 $ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v0.9 -> v0.9

远程标签删除

#先删除本地
$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)
# 之后执行远程删除命令
$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
 - [deleted]         v0.9

3.6、gitignore

​ 有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定不爽。好在Git考虑到了大家的感受,这个问题解决起来也很简单,在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。

​ 忽略文件的原则是:

  1. 忽略操作系统自动生成的文件,比如缩略图等;
  2. 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
  3. 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:
db.ini
deploy_key_rsa

Search

    欢迎添加我的个人微信号

    个人微信哦

    Table of Contents