git的17小问
1 集中式vs分布式

集中式:干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本--svn等;
最大的毛病就是必须联网才能工作,如果在局域网内还好,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟。
分布式:

仅仅是增加了本地库这个概念,其余的概念与集中管理并无区别。
各个开发者在本地电脑上都有个本地仓库,在无网络的情况下,可以将代码提交到本地仓库;然后等网络恢复时,就可以push本地提交的代码到中央服务器。
2 git工作流程--重要

工作区、暂存区(索引区)、本地仓库、远程仓库

执行完add操作后,暂存区的内容则会被清空,转移进本地仓库中;

3 git工作状态与文件颜色

红色---未跟踪(Untracked)---刚创建好文件,该文件还未被git管理,则需要执行git add
绿色---已暂存(Staged)---执行add操作后,文件被放于暂存区(又叫索引区)
蓝色---已修改(Modified)---文件有改动,但还没有提交commit到本地仓库
白色---未修改(Unmodified)---文件已经提交,没有改动
灰色---已忽略(ignored)---版本控制已忽略文件
-----一看文件颜色,就知道这个文件的状态
4 对分支的理解----->数据结构中,链表和指针的概念。
一个分支代表一条独立的开发线。
master,又叫主分支,被git自动创建,是一个指针且指向最新的一次提交;
HEAD也是一个指针,总是指向当前分支;

创建分支:
其实是新建一个指针。新建dev分支,其实是有两步操作
1 新建指针dev,将该指针指向最新的提交节点
2 将head指针指向dev

接下来,我们进行一次提交操作:

整体变成这样?
为什么dev指针向前了,但是master分支依旧不变,
如果我们现在在dev分支完成操作了,想把dev分支合并到master分支?
----直接把master指针指向dev的当前提交,就完成合并merge操作。

使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作
Git 分支实际上是指向更改快照的指针。
5 git命令
(1) git init
用于创建一个仓库:会生成一个.git文件,只要把这个文件跟项目代码放一起,这个项目便用git管理起来了。

(2) git checkout --- 切换分支
切换本地分支
git checkout branchname
git checkout -b 本地分支名 origin/远程分支名
操作:1:将远程仓库里指定的分支拉取到本地,
2:并在本地创建一个分支与指定远程仓库分支关联起来
3: 并切换到新建的本地分支中
(3) git log
因为,每提交一个新版本,实际上Git就会把它们自动串成一条时间线,每一次提交都可以有一个commit id(版本号),是一个SHA1计算出来的一个非常大的数字,用十六进制表示,40位;用git log可以看到

(4) git reset----版本回退
- 看看有哪些提交,每次提交对应的commit id
- 把当前版本append GPL回退到某个版本,使用
git reset --hard 1094a ---版本号没必要写全,前几位就可以了,Git会自动去找
6 .git目录

(1)config:
该文件包含你的仓库配置,比如远程的url,你的邮箱和用户名等,每次你在控制台使用git config都会在此产生影响
(2)hooks--钩子
一些自定义脚本,这些脚本主要用于在特定的命令和操作之前或者之后进行特定的处理
比如:执行完push操作以后,我们希望进行项目打包操作,则这个项目打包操作的脚本则放在这个hooks中
(3)Info--存放ignore,那些不被git管理的文件
(4)Index--暂存区的文件
(5)refs:

Heads:本地仓库的分支
Remotes:远程仓库的分支
Tags:一些重要时刻的标签;
(6)objects:
Git的对象都保存在这里。
有点像unix操作系统的文件管理方式。
这个值得深究!!但复杂。之后如果有机会,可以再次就这个进行探讨。

7 git config
这两条配置很重要,每次Git提交时都会引用这两条信息,
说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录:
git config --global user.name "Spring"
git config --global user.email Spring@163.com
--global 代表是全局设置,所有项目均可以使用
如果你希望在一个特定的项目中使用不同的名称或e-mail地址,
你可以在该项目中运行该命令而不要–global选项 ---->git config user.name "Spring"
8 git安全
Ssh 远程连接
为什么需要ssh? ----信息进行网络传输(本地仓库和远程仓库上的交互),不希望代码在信息被截胡被篡改 ,所以需要对信息进行加解密。
私钥放于你本地,用于加密;
公钥需要配置在git远程服务器上,用于解密;
9 .gitignore
不是所有本地仓库的文件都上传到远程仓库中,由远程仓库进行管理的;

10 git冲突

master分支和feature1分支各自都分别有新的提交;
此时执行git merge feature1

原因:当同一个文件的同一行代码,有两个版本。git没有办法“快速合并fast-forward”,只能试图把各自的修改合并起来,但可能发生冲突;
也可以,直接查看冲突的文件:

我们决定保留什么,舍弃什么以后,进行再次提交,

很重要::合并的时候一定不要简单粗暴的直接选择自己的版本,一定要去看冲突具体位置,不要把别人的提交覆盖了。
11 git pull失败?怎么解决?
原因:如果本地有文件改动未提交,且该文件和服务器最新版本有冲突,提示:

解决:
1 强制覆盖掉自己的本地修改(不推荐,个人修改代码未保存)
git reset --hard //强制覆盖
git pull
2 将修改保存到暂存区
git stash //推送一个新的储藏
git pull //拉取
git stash pop //从暂存区取出储藏 (更新后的代码和自己写的代码合并,可能存在冲突,需要手动解决冲突)
注意:
从暂存区获取后,依然可能出现无法pull新代码的问题,报错为:

3、解决方法:

Pull or push? It is a question.
12 为什么建议你先git pull,再commit?
正确的提交思路是:先获取远程仓库最新的代码,
与本地代码进行合并(如果发生冲突则手动解决冲突),
然后再将合并后的代码进行远程提交;
----否则你commit后还未来得及push,此时其他人向远程仓库提交了同个文件同个位置的代码,那你会push失败的,也会pull失败。进退两难。
13 忘记pull,而是直接commit了,且push失败,怎么解决?
解决方案:
git fetch origin dev 将远程仓库拉到本地
2.git merge FETCH_HEAD 合并,手动解决冲突
3.git push origin dev 将本地代码提交push到远程dev分支
----解决办法不止一种,了解原理后可以用自己独有的方式解决
14 打tag--标签管理
用处:发布版本时通常会需要打一个标签,是为了在未来某个时刻,看看某个版本的代码,可以直接取用某个版本的代码。
tag就是一个让人容易记住的有意义的名字(取个别名,而不是用commit_id)
创建标签:git tag v1.0
拉取指定标签的代码:git checkout v1.0
15 如果已经有了一个项目,怎么将其用git管理?
在其根目录下,执行git init(创建本地仓库) --->git add .---->git commit--->git commit
16 如果在git远程仓库创建了一个新的仓库,
该怎么与自己的项目关联起来?如果不想让项目被git管理了,又怎么办?
1 将代码git clone下来,则本地会有了一个.git文件夹
2 将自己的项目跟git文件夹放在一起
17 好用的工具推荐 sourceTree
非常好用!! 甚至是git官方进行推荐的工具。
当我们对Git的提交、分支已经非常熟悉,可以熟练使用命令操作Git后,再使用GUI工具,就可以更高效。SourceTree可以操作任何的git库,界面非常直观。

浙公网安备 33010602011771号