git的安装与基础操作

Git简介

git是什么?

Git 是目前世界上最先进的分布式版本控制系统(没有之一)。

什么又是版本控制系统?

举个例子:
如果你用 Microsoft Word 写过长篇大论,那你一定有这样的经历:
想删除一个段落,又怕将来想恢复找不回来怎么办?有办法,先把当前文件“另存为……”一个新的 Word文件,再接着改,改到一定程度,再“另存为……”一个新文件,这样一直改下去,最后你的 Word 文档变成了这样:
在这里插入图片描述
过了一周,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找,真麻烦。看着一堆乱七八糟的文件,想保留最新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删,郁闷不郁闷?

更要命的是,有些部分需要你的财务同事帮助填写,于是你把文件 Copy 到 U 盘里给她(也可能通过Email 发送一份给她),然后,你继续修改 Word 文件。一天后,同事再把 Word 文件传给你,此时,你必须想想,发给她之后到你收到她的文件期间,你作了哪些改动,得把你的改动和她的部分合并,繁琐不繁琐?看到头都大了,于是git就诞生了。

git的演变历程(不要嫌啰嗦,真的很有趣!)

很多人都知道,linux 在 1991 年创建了开源的 Linux,从此,Linux 系统不断发展,已经成为最大的服务器系统软件了。

林纳斯·本纳第克特·托瓦兹虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那 Linux 的代码是如何管理的呢?
事实是,在 2002 年以前,世界各地的志愿者把源代码文件通过 diff 的方式发给 linux,然后由 linux本人通过手工方式合并代码!

你也许会想,为什么 linux 不把 Linux 代码放到版本控制系统里呢?不是有 CVS、SVN 这些免费的版本控制系统吗?因为 linux 坚定地反对 CVS 和 SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比 CVS、SVN 好用,但那是付费的,和 Linux 的开源精神不符。

不过,到了 2002 年,Linux 系统已经发展了十年了,代码库之大让 linux 很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是 linux 选择了一个商业的版本控制系统 BitKeeper,
BitKeeper 的东家 BitMover 公司出于人道主义精神,授权 Linux 社区免费使用这个版本控制系统。

安定团结的大好局面在 2005 年就被打破了,原因是 Linux 社区牛人聚集,不免沾染了一些梁山好汉的“江湖习气”。开发 Samba 的 Andrew 试图破解 BitKeeper 的协议(这么干的其实也不只他一个),被BitMover 公司发现了(监控工作做得不错!),于是 BitMover 公司怒了,要收回 Linux 社区的免费使用权。
linux 可以向 BitMover 公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:
linux 花了两周时间自己用 C 写了一个分布式版本控制系统,这就是 Git!一个月之内,Linux 系统的源码已经由 Git 管理了!牛是怎么定义的呢?大家可以体会一下。

Git 迅速成为最流行的分布式版本控制系统,尤其是 2008 年,GitHub 网站上线了,它为开源项目免费提供 Git 存储,无数开源项目开始迁移至 GitHub,包括 jQuery,PHP,Ruby 等等。
历史就是这么偶然,如果不是当年 BitMover 公司威胁 Linux 社区,可能现在我们就没有免费而超级好用的 Git 了。

Git分布式版本控制系统的特点:

  • 分布式版本控制系统根本没有“中央服务器”
  • 工作的时候,不需要联网
  • 分布式版本控制系统的安全性要高,冗余性高
  • 极其强大的分支管理
  • 远程管理

安装git

最早 Git 是在 Linux 上开发的,很长一段时间内,Git 也只能在 Linux 和 Unix 系统上跑。不过,慢慢地有人把它移植到了 Windows 上。现在,Git 可以在 Linux、Unix、Mac 和 Windows 这几大平台上正常运行了。

再linux上安装git

首先,你可以试着输入 git,看看系统有没有安装 git:

$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

像上面的命令,有很多 Linux 会友好地告诉你 Git 没有安装,还会告诉你如何安装 Git。如果你碰巧用 DebianUbuntu Linux,通过一条 sudo apt-get install git就可以直接完成 Git 的安装,非常简单

如果是其他 Linux 版本,可以直接通过源码安装。先从 Git 官网下载源码(网站服务器在国外,建议翻墙访问,否则太慢或无法访问)
https://git-scm.com/download/linux

在这里插入图片描述
点进去后选择一个你想安装的版本下载下来
在这里插入图片描述
把源码包拷贝到Centos下你想要放的目录,解压,./configure后make,make ,make instll 依次执行
在解压前呢,先准备一下git所需要的依赖环境

# CentOS:
[-> #~ ] yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
 
# Ubuntu:
[-> #~ ] apt-get install -y libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev 

如果想以后git支持多文本,如.docx,.html等,可以做这一步(选做)

# CentOS:
[-> #~ ] yum install -y asciidoc xmlto docbook2x 
 
# Ubuntu:
[-> #~ ] apt-get install -y asciidoc xmlto docbook2x 

编译安装

tar zxf git-2.9.5.tar.gz 
cd git-2.9.5/
make configure
./configure --prefix=/usr/local/git
make && make install

安装完成后呢,为了方便使用,优化执行路径:

ln -s /usr/local/git/bin/git /usr/bin/

可以试着使用git --version来查看版本
在这里插入图片描述

在 Mac OS X 上安装 Git

如果你正在使用 Mac 做开发,有两种安装 Git 的方法。

一是安装 homebrew,然后通过 homebrew 安装 Git,具体方法请参考 homebrew 的文档:http://brew.sh/

第二种方法更简单,也是推荐的方法,就是直接从 AppStore 安装Xcode,Xcode 集成了 Git,不过默认没有安装,
你需要运行 Xcode,选择菜单“Xcode”->“Preferences”,在弹出窗口中找到“Downloads”,选择“Command Line Tools”, 点“Install”就可以完成安装了。

在这里插入图片描述

在 Windows 上安装 Git

在 Windows 上使用 Git,可以从 Git 官网下载:
https://git-scm.com/download/
然后选择win,进去就自动下载Git-2.26.2-64-bit.exe,下载完,直接运行
安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明 Git 安装成功!
在这里插入图片描述
安装完成后,还要声明自己的名字和邮箱

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

注意 git config 命令的--global参数,用了这个参数,表示你这台机器上所有的 Git 仓库都会使用这个配置;
当然也可以对某个仓库指定不同的用户名和 Email 地址。

bit的基础操作

创建版本库目录并初始化

[root@localhost /]# mkdir git
[root@localhost /]# cd git/
[root@localhost git]# git init  #初始化
Initialized empty Git repository in /git/.git/
[root@localhost git]# 

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

咦,/git/.git/下的.git什么东西?
这个目录是 Git 来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把 Git 仓库给破坏了。
如果你没有看到.git 目录,那是因为这个目录默认是隐藏的,用 ls -ah 命令就可以看见。
在这里插入图片描述
在这里插入图片描述

注:
    branched  分支目录
	config    定义目录特有的配置选项
	description 仅供git web使用
	HEAD 	  指定当前的分支
	hooks	  git钩子文件
	info 	  包含一个全局排除文件(exclude)
	objects	  存放所有的数据内容 
	refs	  指针文件
	index     暂存区文件

把文件添加到版本库(或上传代码)

上传代码步骤分为2步:
1>把代码或文件上传到暂存区
2>再上传到版本库
首先,编写一个test.php

vim /git/test.php
<?
phpinfo();
?>

上传到暂存区


执行上面的命令,没有任何显示,这就对了

git add test.php 表示的是单个文件上传
git add . 表示的是当前目录所有文件上传

用命令 git commit 告诉 Git,把文件提交到仓库

[root@localhost git]# git commit -m 'add test.php'
[master (root-commit) 0af70ac] add test.php
 1 file changed, 3 insertions(+)
 create mode 100644 test.php
[root@localhost git]#

git commit命令,-m 后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

为什么 Git 添加文件需要 add,commit 一共两步呢?
因为commit可以一次提交很多文件,所以你可以多次 add 不同
的文件,相当于公交车一样,拉一车人会走,拉你一个人也走的道理;
如下:

$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

我们已经成功添加并提交一个文件后,继续工作,于是,我们修改test.php

# This is a test script
<?
phpinfo();
?>

git status命令可以让我们时刻掌握仓库当前的状态,下面的命令告诉我们,test.php被修改过了,但还没有准备提交的修改。
在这里插入图片描述
git diff顾名思义就是查看 difference,显示的格式正是 Unix 通用的 diff 格式,可以从下面的命令输出看到:

[root@localhost git]# git diff test.php 
diff --git a/test.php b/test.php
index 1442a01..3aa80b5 100644
--- a/test.php
+++ b/test.php
@@ -1,3 +1,4 @@
+# This is a test script
 <?
 phpinfo();
 ?>
[root@localhost git]# 

知道了对 test.php作了什么修改后,再把它提交到仓库就放心多了,提交修改和提交新文件是一样的两步

[root@localhost git]# git add test.php 
[root@localhost git]# git commit -m 'add zhushi'
[master 53ffab0] add zhushi
 1 file changed, 1 insertion(+)
[root@localhost git]# git status
# On branch master
nothing to commit, working directory clean #提示我们没有要修改的,目录是干净的
[root@localhost git]# 

当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在 Git 中,我们用 git log 命令查看,其中,
git log --oneline #显示摘要信息

[root@localhost git]# git log
commit 53ffab060985864deae700ab84b294db9addcc54
Author: lzs <[email protected]>
Date:   Thu Apr 30 06:08:21 2020 -0700

    add zhushi

commit 0af70ac06b78b139b2648acf3b27c670114b70ba
Author: lzs <[email protected]>
Date:   Thu Apr 30 04:17:59 2020 -0700

    add test.php

[root@localhost git]# git log --oneline  
53ffab0 add zhushi
0af70ac add test.php

版本回滚

git reset --hard HEAD^ #回滚到上个版本,HEAD^^上上版本,HEAD~10回滚到上10个版本
我们来做个测试:

[root@localhost git]# git reset --hard HEAD^
HEAD is now at 0af70ac add test.php
[root@localhost git]# 

这就好比我们做时光机回去过去了,可是这里呆够了,又想回去了,该咋办?办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到你要回去的commit 的id是53ffab0,还是可以的
命令:
git reset --hard 53ffab0 #通告git log 的版本号码回滚,仅写前7位就可
例子:

[root@localhost git]# git reset --hard 53ffab0 
HEAD is now at 53ffab0 add test.php
[root@localhost git]# cat test.php 
# This is a test script
<?
phpinfo();
?>
[root@localhost git]# 

在 Git 中,总是有后悔药可以吃的。Git 提供了一个命令 git reflog用来记录你的每一次命令:
在这里插入图片描述

工作区和暂存区

工作区: 就是你在电脑里能看到的目录,比如我的 git目录就是一个工作区
工作区有一个隐藏目录.git,这个不算工作区,而是 Git 的版本库。

Git 的版本库里存了很多东西,其中最重要的就是称为 stage(或者叫 index)的暂存区,还有 Git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针叫 HEAD

因为我们创建 Git 版本库时,Git 自动为我们创建了唯一一个 master 分支,所以,现在,git commit就是往 master分支上提交更改。
他们之间的关系如下图:
在这里插入图片描述

撤销修改

场景 1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git checkout -- file,把文件在工作区的修改全部撤销

场景 2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD file,就回到了场景 1,第二步按场景 1 操作。

场景 3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退,回退到之前的位置即可
例子:

[root@localhost git]# cat abc.txt  #在原来的基础上加上一行qqqqqqqqq
aaaaaaaaaaaaaaaa
vbbbbbbbbbbbbbbbbbb
qqqqqqqqqqqqq
ccccccccccccc
[root@localhost git]# git add abc.txt 
[root@localhost git]# git commit -m 'abc.txt'
[root@localhost git]# git reset HEAD abc.txt 
Unstaged changes after reset:
M	abc.txt
[root@localhost git]# git checkout -- abc.txt 
[root@localhost git]# cat abc.txt 
aaaaaaaaaaaaaaaa
vbbbbbbbbbbbbbbbbbb
ccccccccccccc

删除文件

在 Git 中,删除也是一个修改操作,现在,我们在工作区把abc.txt删除了,因此,工作区和版本库就不一致了,查看状态会立刻出现提示
在这里插入图片描述
现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令 git rm删掉,并且 git commit

[root@localhost git]# git rm abc.txt
rm 'abc.txt'
[root@localhost git]# git commit -m 'remove abc.txt'
[master 7e9f706] remove abc.txt
 1 file changed, 3 deletions(-)
 delete mode 100644 abc.txt
[root@localhost git]# git log --oneline
7e9f706 remove abc.txt
6014302 abc.txt
53ffab0 add test.php
0af70ac add test.php

另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本
git checkout -- abc.txt

还有就是已经把版本库删除了。才发现误删了。也没关系,坐时光机回去呗

[root@localhost git]# ls
test.php
[root@localhost git]# git reset --hard HEAD^
HEAD is now at 6014302 abc.txt
[root@localhost git]# 
[root@localhost git]# ls
abc.txt  test.php

分支管理

什么是分支?
区别于主代码库,创建出来用于新增功能或模块的分支库,仅用户自己有权访问,修改后合并,一般用于更新版本或添加补丁。

例子:
分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习 Git 的时候,另一个你正在另一个平行宇宙里努力学习SVN。
如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了 Git 又学会了 SVN!

在这里插入图片描述
分支在实际中有什么用呢?

假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了 50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

分支工作的原理

版本回退里,你已经知道,每次提交,Git 都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在 Git 里,这个分支叫主分支,即 master 分支HEAD严格来说不是指向提交,而是指向 master,master才是指向提交的,所以,HEAD 指向的就是当前分支

一开始的时候,master 分支是一条线,Git master 指向最新的提交,再用 HEAD 指master,就能确定当前分支,以及当前分支的提交点;每次提交,master 分支都会向前移动一步,这样,随着你不断提交,master 分支的线也越来越长;
在这里插入图片描述

当我们创建新的分支,例如 dev时,Git 新建了一个指针叫dev,指向master 相同的提交,再把 HEAD指向dev,就表示当前分支在 dev上:

在这里插入图片描述
从现在开始,对工作区的修改和提交就是针对 dev分支了,比如新提交一次后,dev指针往前移动一步,而master 指针不变

在这里插入图片描述

假如我们在 dev上的工作完成了,就可以把dev合并到 master上。Git 怎么合并呢?最简单的方法,就是直接把 master指向 dev 的当前提交,就完成了合并
在这里插入图片描述
合并完分支后,甚至可以删除 dev 分支。删除 dev 分支就是把 dev 指针给删掉,删掉后,我们就剩下了一条 master分支.

在这里插入图片描述

分支的创建于合并

查看分支

[root@localhost git]# git branch
* master
[root@localhost git]# 

创建分支

[root@localhost git]# git branch ops
[root@localhost git]# git branch
  ops
* master

创建并切换分支

[root@localhost git]# git checkout -b dev
Switched to a new branch 'dev'
[root@localhost git]# git branch
* dev
  master
  ops

会发现*号跑到了dev分支上,表示的是dev现在是当前分支,现在在dev分支里向git仓库添加文件

echo 'Hello Word!' > /git/hw.txt
git add hw.txt
git commit -m 'branch test'

合并分支

现在,dev 分支的工作完成,我们就可以切换回 master 分支

[root@localhost git]# git checkout master
Switched to branch 'master'

切换回 master 分支后,再查看一个 hw.txt 文件,刚才添加的内容不见了!因为那个提交是在 dev 分支上,而 master分支此刻的提交点并没有变
在这里插入图片描述
现在,我们把 dev 分支的工作成果合并到 master 分支上

[root@localhost git]# ls     #合并前 
test.php
[root@localhost git]# git merge dev
Updating 7e9f706..2dea9e9
Fast-forward
 hw.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 hw.txt
[root@localhost git]# ls     #合并后
hw.txt  test.php

删除分支

合并完成后,就可以放心地删除 dev 分支了

[root@localhost git]# git branch -d ops
Deleted branch ops (was 7e9f706).
[root@localhost git]# git branch -d dev
Deleted branch dev (was 2dea9e9).
[root@localhost git]# git branch
* master

解决合并冲突

在建立一个人分支,修改hw.txt文件,然后git add ,接着git commit 放入本地仓库
切换到master分支上,再对hw.txt进行修改,然后发布到本地仓库
合并,会发现不会成功,但hw.txt的出处会给你标出来

[root@localhost git]# git checkout -b lzs
Switched to a new branch 'lzs'
[root@localhost git]# vim hw.txt 
[root@localhost git]# git add hw.txt 
[root@localhost git]# git commit -m 'lzs kw.txt'
[lzs 5df22d7] lzs kw.txt
[root@localhost git]# git checkout master
Switched to branch 'master'
[root@localhost git]# vim hw.txt 
[root@localhost git]# git add  hw.txt
[root@localhost git]# git commit -m 'master he.txt'

合并会发现

[root@localhost git]# git merge lzs
Auto-merging hw.txt
CONFLICT (content): Merge conflict in hw.txt
Automatic merge failed; fix conflicts and then commit the result.

文件不一样的地方会标记出来,在master上修改完,在上传仓库就好


[root@localhost git]# cat hw.txt 
<<<<<<< HEAD
Hello word!
=======
Hello WORD!
>>>>>>> lzs

[root@localhost git]# vim hw.txt 
[root@localhost git]# git add hw.txt 
[root@localhost git]# git commit -m 'fixed hw.txt'
[root@localhost git]# cat hw.txt 
Hello WOrd!

下一篇:Git的远程管理

原创文章 58 获赞 20 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43815140/article/details/105865600