Skip to content

Latest commit

 

History

History
510 lines (243 loc) · 21.2 KB

README.md

File metadata and controls

510 lines (243 loc) · 21.2 KB

Git:版本控制系统

一、示意图

1568079388406

说明:

1.Workspace:工作区,即平时开发写代码的地方,比如IDE等开发工具,未受git管理;

2.Index:暂存区(索引区),通过git add命令添加文件进来受git监控与管理;

3.Repository:本地仓库,通过git commit命令提交文件进来;

4.Remote:远程仓库、git服务器,通过git push命令将本地仓库文件推送到远程仓库进行同步,保持一致;

二、基本命令

1.git init

新建空文件夹gitstudy,并进入该文件夹运行命令:git init,如下图所示:

1568079884510

​ 执行命令后,会提示初始化空的git版本仓库,并自动生成一个隐藏文件夹.git,包含git的各种配置文件和依赖环境,不懂git的同学,务必不要随意更改此文件夹中的任何内容。

​ 现在,文件夹gitstudy已经是一个本地git仓库了。。。

2.git config --global

在开始正式使用git之前,务必先自报家门,使用命令git config --global user.name "xiao yuan"和git config --global user.email "yuan.xiao@mail.foxconn.com",这样以后在每次提交文件至本地仓库时,都会带上这个消息,在我们排错、提交、回退等操作的时候,会清楚看到是谁提交的。

3.git status

使用命令:git status 查看工作区状态,有没有文件、文件有没有被跟踪、文件有没有被修改等等,如下图所示:

1568080074303

​ 可以看到,没有任何可以提交的文件,提示要先创建或复制文件并且使用命令add进行跟踪,下面创建新的文件1.html。

​ git status -s:可以让输出更简洁明了。

1568086235669

4.git add

创建空文件1.html,并加入git跟踪与管理,使用命令:git add 文件名,如下图所示:

1568080595113

​ 使用git status可以看到文件1.html已经成功加入到暂存区受git跟踪了,这里的跟踪是指文件状态跟踪,如下图所示:

1568080696967

untracked:文件还在工作区,未添加进暂存区,未使用命令add;

unmodified: 文件已经通过add添加进暂存区,而且没有修改过该文件;

modified: 文件被修改过,但未添加进暂存区;

staged:文件被加入暂存区;

通过git commit命令将暂存区文件提交至本地仓库,同时删除暂存区文件。

5.git commit

使用命令git commit可以将暂存区文件提交至本地仓库,参数-m对此次文件提交作文字说明,作为负责任的程序员,这个必须加上,这样在排错、回退的时候,可以知道这个文件修改了什么。

1568082585134

​ commit之前没有设置用户名和邮箱,所以默认设置了root,可以使用参数--reset-author重新设置。此时暂存区文件1.html已经被保存进本地仓库了。

6.git log

使用命令git log可以查看详细的提交事件,包括版本号、作者、时间、描述,如下图所示:

1568082776917

版本号是唯一的,后面可以用于回退和跳转。

7.git reflog

使用命令git reflog可以查看到所有历史事件,包含各种回退和跳转。

1568087643844

[root@localhost gitstudy]# git reflog 3377df6 HEAD@{0}: reset: moving to HEAD^ 978c592 HEAD@{1}: commit: add h5 tag,changed tag 3 and tag 4 3377df6 HEAD@{2}: commit: add h4 tag bcf98bd HEAD@{3}: commit: add h3 tag c6d661d HEAD@{4}: commit (initial): add empty html file

8.git log --pretty=oneline

该命令可以以单行打印的简略信息展现出操作记录

1568093566619

9.git diff filename

使用该命令可以查看工作区和暂存区的文件内容区别,比如a.html文件之前已经add进暂存区了,后来修改了这个文件内容,但没有执行add命令。

1568086983661

再次执行add命令,将修改后的文件加入暂存区,然后使用git diff查看文件区别,结果显示没区别,说明工作区文件的修改已经同步到暂存区了。

10.git diff --cached filename

该命令用于查看暂存区和本地仓库最新版本的文件区别,一旦文件从暂存区commit到仓库后,那么暂存区和本地仓库中的文件是没有任何区别的;如果文件没有commit,那么暂存区跟本地仓库中的文件是有区别的。

11.git diff HEAD filename

使用该命令可以查看工作区文件和本地仓库最新版本文件的内容差别,比如修改后的a.html还没用add进暂存区,使用该命令查看本地仓库中的a.html与工作区的a.html有何差别。

1568087166555

执行commit命令,将暂存区的文件a.html提交至本地仓库,然后执行命令git diff HEAD查看两者区别,结果显示无区别,说明已经将暂存区文件同步到本地仓库了。

这里的HEAD表示指针,指向的是本地仓库中最新的一个版本。

12.git pull

用途:将远程仓库文件同步到本地仓库

1570174520204

13.git push

用途:将本地仓库文件同步到远程仓库中

1570174549813

三、回退与跳转

对html文件做三次修改三次提交,来测试版本回退和跳转。

1568086701396

这是第一次修改,后面两次随便添加东西即可。修改完后,使用命令git log查看所有提交的事件。

1.修改事件准备

1568087579283

2.回退到上一个版本:git reset --hard [HEAD^|版本号]

HEAD表示指针,^表示回退一次,即上一次修改状态,我们执行一下这个命令,如下所示:

1568094002390

当要回退到以前第10个版本时,我们不可能在HEAD后面加10个^,因此,有另外一种办法可以直接回退到任一版本,就是--hard后面加事件的版本号(建议写完整的版本号,前6位也行,不过事件多的时候可能会重复)。如git reset --hard bcf98b

3.回退到最新版本:git reset --hard 版本号

由于之前回退到旧版本后,命令git log显示不出最新版本的版本号,根据这条命令的输出我们无法回到最新版本中。此时,有另外一条命令可以查看到所有事件的版本号,就是git reflog,如下图所示:

1568094560509

这个命令的输出会显示所有操作的事件信息,如要回到最新版本事件,那么只需要找到它的版本号即可。

执行命令:git reset --hard 978c592回退到最新版本

1568098658007

四、高级命令

1.撤销操作:git checkout -- | git reset HEAD filename

撤销情景一:工作区文件被修改且没有执行add+commit操作。

此时执行命令git status其实已经显示了如何撤销修改了,如图所示:

1568101082594

执行命令:git checkout -- b.md,结果如下:

1568101253206

撤销情景二:工作区文件被修改且执行add操作但没commit。

如下图所示:提示使用命令git reset HEAD filename可以撤销已经加入暂存区的文件修改。

1568102069336

执行命令:git reset HEAD b.md,可以将文件撤销到未加入暂存区,如下图所示:

1568102258388

此时文件跟情景一一致了,然后使用命令git checkout -- b.md可彻底撤销。

2.删除操作:特殊的修改撤销操作

删除文件a.html进行测试,可以看到当前工作区的状态,因为文件已经在本地仓库中,删除后工作区和本地仓库文件状态不同步,需要同步到本地仓库。此时可以通过命令git diff和git diff HEAD查看文件区别。

1568107425072

删除操作还未同步到暂存区,如果要撤销删除操作,使用git checkout -- a.html即可,如下图所示,删掉的文件a.html又回来了。

1568107859810

要想继续删除文件,将信息从暂存区同步到本地仓库,根据提示信息,执行同步删除操作的命令:git rm a.html,此时要删除的文件不在工作区和暂存区了,继续执行commit命令,即可删除本地仓库中的文件a.html。

1568159253865

如果此时又不想删除文件了,可以使用命令:git reset HEAD a.html将文件恢复到暂存区,然后再执行:git checkout -- a.html恢复到工作区即可。跟撤销修改操作是一样的,分两步恢复。

注意:

1.如果你确实要删除,那么直接rm + git rm + git commit即可,如果你后悔了,想让它回来,版本回退即可。

2.如果先创造文件再删除文件,这时的暂存区与版本库是没有你创造的那个文件的,遇到这种情况,格外注意一下即可。

五、Git工作原理

1.概念

Git与集中式版本管理系统不同的是,多了个暂存区的概念,也正是因为这个暂存区的概念,Git逻辑清晰,功能强大,成为了最先进的分布式版本控制系统。

先来看看工作区的概念,所谓工作区就是learngit文件夹,是经过git init配置好的git仓库

我们知道,配置git仓库的时候,产生了一个.git的隐藏目录,这儿是Git的版本库

在这个.git版本库里面最重要的概念就是暂存区,可以称作为stage(或index)

1568097660928

所以我们的add+commit的详细流程到底是什么?如上图所示:

就是我在工作区的时候创建或修改了文件或文件夹,然后使用add命令的时候,将文件或文件夹加入暂存区,再使用commit提交的时候,将暂存区的所有内容正式同步到当前master的分支Git仓库,产生了新的版本号,HEAD指针向上移动指向了新的版本号,完成Git仓库内容的更新。

2.git diff总结

我们在工作区改动文件、添加到暂存区,提交到版本库这三个阶段走来,git diff总能发挥出对比状态的作用

①git diff filename:比较文件在工作区与暂存区的变化(在工作区改动文件,还未add+commit)

②git diff --cache filename:比较文件暂存区与当前版本库的变化(已经将文件添加进去暂存区,但还未提交)

③git diff HEAD filename:比较工作区与当前版本库的变化(说白了,就是看你的改动还没被commit)

3.撤销修改和删除操作总结

说实话,其实修改与删除都属于"修改",操作没有本质区别,所以我将这两个放到一起总结

①当你在工作区修改或删除的时候,想要撤销,统一git checkout -- filename(两个横杠不能省略)

②当你的修改或删除真的要确定的话,进一步git add/rm,然后commit上去。如果你执行了加入暂存区过后,你后悔了,想要撤销就git reset HEAD filename,将暂存区的变动回退。当然了,你还可以进一步地git checkout -- filename直接回到最初的状态,装作无事发生。

③当你的修改或删除,都走了add+commit的步骤,这个时候直接版本回退即可。

六、本地仓库和GitHub仓库互访

1.本地仓库生成ssh公钥

1570153827408

2.登录GitHub,新建ssh key

如下图所示:

1570155488421

点击右边的 New SSH key,把刚才在本地仓库生成的ssh 公钥 内容复制进去保存即可。

1570156194036

1570156270406

完成后,可看到如下界面:

1570156596681

至此,本地仓库和GitHub远程仓库可互相连接了。。。 <<<<<<< HEAD

3.创建GitHub远程仓库

这个仓库名称必须和本地仓库的名称相同才能push

1570158569764

1570158777711

4.同步本地仓库和GitHub远程仓库

根据上图所示,使用两条命令,可以将本地仓库中的文件同步到GitHub远程仓库中

命令一:git remote add origin git@github.com:xiaoyuan2019/testgit.git

解释:git remote,就是管理远程仓库的意思,add origin,就是添加远程库的意思,origin是可以改的,只是给远程库取个名字而已,然后后面的一大串就是远程库的地址,这是Github直接提供给我们的,当我们输入了这条命令之后,肯定没有反应的。因为这条命令相当于告诉Git有这么一个远程仓库,接下来就是正式地推送步骤。

命令二:git push -u origin master

解释:将master分支的这个Git仓库推送到远程库,当你输入的时候,因为你是第一次使用Git与Github,会有个SSH链接让你确定是否信任,直接输入yes就可以,以后不会再询问。而那个-u是一个初始参数,因为我们是第一次推送,这样做是将本地Git仓库与Github上远程仓库给关联起来。

此时,刷新一下GitHub仓库页面,就会发现本地仓库的文件已经同步到GitHub了。

1570159165902

5.修改本地仓库并同步到远程仓库

修改同步很简单,在本地仓库中修改文件,经过一通add\commit\push后,刷新GitHub页面,就可以看到修改的内容已经同步到远程仓库了。(前提是没有修改远程仓库文件)

git add
git commit -m '修改了第58行的标题'
git push origin master
6.本地仓库同步到远程仓库之前修改了远程仓库

此时git push会出现如下错误,原因是本地仓库和远程仓库文件不一致,远程仓库里的文件,在本地没找到,也就是说远程仓库里的内容比本地仓库还要新,这是由于多人合作开发,其他小伙伴写完内容后提交到远程仓库,你没有把最新版本pull下来,或者你现在使用版本是老版本。

1570173581323

解决办法:在每次提交前先使用git pull 命令把远程仓库里最新的内容拿下来,然后再执行push操作,git pull相当于把最新代码拿下来并于现有代码进行合并。

1570174520204

1570174549813

7.克隆

所谓的克隆项目,实际上就是与上面相反的过程,上面是从本地仓库推送同步到Github仓库,使用了git push,

克隆意思是从GitHub远程仓库把文件复制到本地来,使用git clone。

我们进入GitHub的gitstudy仓库,点击右上角的clone即可。(路径下不能存在跟需要clone的远程仓库同名文件夹)

1570160703050

在本地执行命令:git clone git@github.com:xiaoyuan2019/gitstudy.git

等下载完成后,可以看到文件夹gitstudy以及里面的文件了。

1570160914501

七、Git分支

1.概念

原作者的项目是master分支就是主分支,其他开发者要修改主分支的话,就必须先clone master到本地仓库,然后创建新分支,我们的所有开发动作都在这个新分支上面,不会影响主分支,修改后pull request给master主分支审核,就是新分支合并进主分支,这样就实现了多人协同开发项目的目的,这就是分支的概念。所谓备胎分支就是创建分支和合并分支的过程。

2.创建分支、切换分支、查看分支

创建分支:git branch 分支名称

切换分支:git checkout 分支名称

查看分支:git branch

创建分支并切换到分支:git branch -b 分支名称

1570235887364.

3.在分支xiaoyuan上修改文件并查看状态

修改文件并进行add、commit操作,此时是在分支xiaoyuan上进行的操作,不会影响master主分支的数据。

1570237814047

此时,可以同步分支xiaoyuan到远程仓库中,发现是同步不了的,因为远程仓库中不存在分支xiaoyuan。

4.合并分支、删除分支

将分支xiaoyuan合并到主分支master中,前提是分支xiaoyuan中的文件都commit过,否则无法切换到主分区master中,如下图所示:

1570238492329

当我们add、commit后,就可以直接在分支test中切换到master中,然后我们在master中进行分支合并,如下:

1570238703185

切换成功。注意:当我们切换到master中时,文件内容会回到master中,而不是在分支test中的状态,当我们合并成功后,文件内容会立即更新回最新状态,因为这时分支test中的修改已经同步到主分支master中了。我们可以打开md文件,观察切换和合并分支时,md文件会出现两次闪烁的状态,随后去查看md文件内容,可以发现正好是切换前和切换后的内容更新导致的。

合并完成后,分支test和xiaoyuan不再需要了,可以直接删除掉。 1570238991676

5.切换分支

当前分支上的工作还没做完,不能add+commit提交,但又想去其他分支,这个时候我们该怎么办?

可以通过命令:git stash 隐藏当前分支工作区,并生成隐藏任务列表,如下:

1570240699719

继续回到当前分支进行工作区任务开发,怎么恢复隐藏工作区任务?

使用命令:git stash pop(相当于两条命令:git stash apply 和 git stash drop)恢复工作区并删除隐藏任务

6.分支命令总结

查看所有的分支:git branch

创建并切换到新的分支:git checkout -b

合并某分支到当前分支:git merge

删除掉指定的分支:git branch -d

创建分支:git branch

切换分支:git checkout

隐藏当前工作区:git stash

八、协作分支

1.介绍

多人开发时,每个人必须在master分支上各自建立自己的分支,这样每个人都是独立开发,不会互相影响,更不会影响到master分支。当各自的分支开发完后,经过add\commit后,切换到master分支进行合并操作git merge A,将自己的分支内容合并进master主分支,这样就完成了协同开发的目的。如果在开发过程中,自己要去帮助同事解决他分支中的Bug问题,那么自己首先利用git stash隐藏自己的工作区,然后切换至同事的分支,为了避免影响同事的开发内容,最好自己在同事的分支基础上再新建一个专门解决bug的分支,当bug解决完后,切换回同事分支进行合并即可。

2.总结(一)

当你合并分支的时候遇到冲突,修改冲突以后再add+commit,即可合并成功。

对了,合并分支的时候最好不要直接git merge,而是选择带分支记录并重定义提交语句的合并方式

git merge --no-ff -m "commit时所需要解释的语句" 被合并分支的名字

(例如:git merge --no-ff -m "modify readme.md with no-ff" A)

一条又臭又长的查看分支日志,但你又不得不去使用:git log --graph --pretty=oneline --abbrev-commit

当你在手头的工作没完成的时候,你必须要去另外一个分支去干活,这个时候你需要git stash保留工作现场

但是你在干活的过程中如果新建了一个文件,请务必先git add再git stash,直到全部git stash干净了为止

然后干完活以后直接git stash pop出栈恢复工作现场

删除你已经工作好的分支的时候,是输入git branch -D 分支的名字,参数是大写的D。

3.总结(二)

当你和你的同事在对于项目的同一个分支开发的时候,你的同事先你一步提交推送

而你准备推送上去的时候,却遇到报错,远程库已经更新,于是你只能

1)先与远程仓库的那个分支取得联系:git branch --set-upstream-to=origin/dev dev

2)然后将远程仓库最新内容同步到本地:git pull

3)遇到合并后的冲突提醒,你于是就修改文件,然后提交:add + commit

4)这个时候,你觉得,相关日志里面应该并到一次记录:git rebase

5)然后你就可以将最终版本推送到远程仓库了:git push origin dev

但是别忘了一切始于开头,到底怎么参与远程仓库某一个分支的协作开发呢?

1)先把项目克隆到本地来:git clone git@github.com:Masterpaopao/learngit.git

2)然后创建并切换到你要参与协作的指定远程分支:git checkout -b dev origin/dev

九、标签管理

1.创建标签

当对一个改动进行add、commit后,可以跟上命令:git tag v1.0,这样就对当前提交的版本打上了tag v1.0,之后就可以通过标签将该版本同步到远程仓库了,如:git push origin v1.0

1570269435740

1570269411014

通过标签可以查看该版本的详细信息,命令:git show v1.0

1570269485382

2.删除标签

命令:git tag -d v1.0