一、Git概述和环境搭建
Git是一个开源的分布式版本控制系统,区别于集中式的系统,Git系统中每一个终端都有一套完整的版本库,脱离了网络,也能管理版本,能提高效率。可以有效、高速地处理从很小到非常大的项目版本管理。
在团队开发中代码同步是非常重要的,大致开发的流程如下:
1.在服务器上创建git仓库
2.开发者A和B从服务器上克隆仓库
3. A和B在本地创建分支,负责开发自己的模块
4. A同步最新代码到本地,推送代码到服务器仓库
5. B同步最新代码到本地,推送代码到服务器仓库
6.如果A和B在更新同步代码的时候有冲突,则解决冲突。若无冲突,则代码自动合并
基本概念:
工作区: 在电脑里能看到的目录。
暂存区: 一般存放在".git目录下”下的index文件 (.git/index)中,所以也叫索引
版本库: 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库
使用git add添加一个文件的时候,会先加入到暂存区;
通过git commit之后,暂存区的内容同步到正式的版本库。
1、下载安装git客户端
下载地址:https://git-scm.com/download/
官网下载太慢,转到下载地址2
下载地址2:https://npm.taobao.org/mirrors/git-for-windows/
安装选择2,默认的可以使用cmd,会自动配置环境变量
选择包含cmd命令的安装方式,在cmd输入git命令有命令提示表示成功。
安装完成的目录结构
2、准备远程仓库账号
在我们团队开发,或者把代码共享给其他人的时候,需要有一个远程仓库,常用的远程git服务有:
GitHub( https://github.com/):公有库免费,私有付费。
码云( https://gitee.com):国内的服务商,公有、私有都免费。
GitLab( https://gitlab.com):与前两者不同,GitLab是可以部署到自己服务器上的web服务。
在开始学习git之前,需要注册一个账号,码云或者GitHub的都可以(两个平台是独立的,二者不能通用)。
注册成功之后,打开git安装路径下的git-nash.exe
输入用下面的命令,做一个全局配置,后序提交代码的时候都会携带这个信息,最好用前面注册git的邮箱
git config --global user.name "暱称"
git config --global user.email "邮箱"
之后在电脑用户目录下会出现一个.gitconfig文件,全局配置就设置好了
使用命令:git config --list
可以查看配置信息
–global
参数代表的是全局配置,对当前用户的所有仓库有效,常用
–local
只对某个仓库有效,不写的话默认就是local
–system
对系统所有登录的用户有效,很少用
二、基础命令
创建一个空文件夹用来当本地仓库
在git-bash中切换目录
git中支持linux中的命令,比如
cd
: 打开目录
vim
:编辑文本 :wq
保存并退出
pwd
:是显示当前目录
ls
:显示文件夹中的内容
cat
:查看文件内容
1、git init
初始化版本库
执行 git init
之后在目录里会看到一个 .git 文件夹
2、git add
将文件添加到暂存区
格式:git add 文件名
示例:在目录下手动创建一个文件(随便什么文件都行,就是我们平时用的文件):
git add -u
可以将当前托管的文件一起提交,不需要指定文件名,此时的文件进入了git的 暂存区
3、git status
查看当前暂存区的状态
格式:git status
4、git commit
通过 git commit 命令正式提交到版本库(只提交暂存区中的数据),其中 -m 参数表示的是提交时的注释信息,我们要写好当前版本都修改了什么,方便以后版本回退的时候,退到指定的版本。
格式:git commit -m "备注"
文件提交后,再看暂存区就没有文件了。
commit只提交暂存区中的数据,所以需要先add,如果是文件已经add过了,可以使用-am参数直接提交
格式:git commit -am "备注"
如果想修改最近一次的提交信息message
格式: git commit --amend
进入编辑页面后按i进行编辑,再按esc键退出编辑,:wq
再回车退出
5、git diff
查看文件变动
格式:git diff --cached
查看暂存区和版本库的变动
格式:git diff
查看工作区和暂存区的变动
git diff -- 文件名
:是只查看某一个文件的区别
git diff 分支1 分支2 -- 文件名
查看两个分支之间的区别,分支可以写成commit号
6、git reset
用于回滚(撤销)暂存区中的操作
格式:git reset
7、git mv
文件重命名
格式: git mv 原文件 目标文件
8、git log
查看日志
格式:git log
参数:
--oneline
简洁的查看历史
-n数字
最近几次的记录
--all
查看所有分支所有记录
--graph
图形化方式
9、git checkout
可以从主干或其它分支快速创建一个新分支或切换分支,使用 git checkout 命令,在checkout的时候我们可以指定一个版本号,这个版本号就是在 git log 中查到的hash值。版本号在使用的时候可以只使
用前几位,只要当前的几位能够确定唯一标识就可以。
git checkout -b 新分支 原分支
创建分支
git checkout 分支
切换分支
10、git branch
用于操作git分支
分支是git中非常重要的一个概念,在开发时我们可以创建多个分支,每个分支间是相互独立的,互不影响。当分支开发完毕后,可以选择合并到主干。
格式:git branch -v
看本地有多少分支
格式:git branch -d 分支名
删除分支
11、分离头指针
创建临时分支,可选择保留或丢弃
格式:git checkout hash
修改保存文件提交后切换分支
git log查不到与此记录相关的信息
保存修改的分支
12、gitk
打开图形界面
格式:gitk
可以看到各个版本的信息,包括父子关系、提交时间。tree可以显示目录结构。在View中可以定义显示的视图
13、git rebase
指定修改历史版本中的提交信息
格式:git rebase -i hash值
(hash选的是父亲)
只修改提交信息选择 r 命令,修改后保存
14、git rm
删除一个文件
格式:git rm 文件名
删除工作区中的文件,并把变动放在暂存区
格式:git rm 文件名 --cached
删除暂存区中的文件,不删除工作区
15、git stash
保存暂存区的文件
如果我的文件,有一部分新功能A在暂存区,但临时增加了别的任务B,需要在之前的版本上修改,而我的新功能A还没开发完,这时我们可以使用 git stash 命令来保存暂存区,此时文件会恢复到暂存区之前的样子。
格式:git stash
git stash apply
和 git stash pop
命令都能将stash缓存的东西恢复,区别是apply会将缓存的信息保留在 git stash list
中,而pop则直接移出list。
三、git内部构成
进入到工作区.git目录
1、HEAD
HEAD文件中存放的是当前目录工作的分支
当切换分支后,HEAD的内容会发生改变
查看HEAD和父之间的差异,用 git diff HEAD HEAD^
^
代表parent, ^^
就是父亲的父亲,等同于 ~2
2、refs
refs是引用,里面包含了分支和标签等一些信息
继续查看master文件,可以看见文件中保存的内容是和hash版本号相关的:
3、config
config中记录的是当前目录的配置,通过 git config --local 设置的就是这个文件
4、objects
可以随便打开一个目录,查看文件类型和文件内容(不同的人测试结果可能不同,多切换几个文件夹就能找到文件了):
git中核心的对象主要有 commit , tree 和 blob 三种类型。git中认为两个文件中如果内容相同,就是唯一的一个blob(和内容相关,和文件名无关,节约存储空间)。
在工作区中添加一个test-dir文件夹,并创建两个文件,提交到git中
在gitk中查看,可以看见目录结构
在git中每一个commit对应一个tree,它就是工作区那个文件夹工作区tree下面会有其它的tree和blob,如下图(为方便理解,写了文件名,实际上只跟地址相关,和文件名无关)
四、版本回退
1、暂存区恢复和HEAD一样
格式:git reset HEAD -- 文件名
撤销暂存区中的变动,其中文件名是可选参数,不写就是撤销所有,(它不会撤销你文件中的修改,即不改变工作区,撤销的是add)
2、工作区恢复成暂存区
格式:git checkout --文件名
修改本地文件,然后想恢复到暂存区中的版本
3、回退到历史的commit(慎用)
格式:git reset --hard 版本
可以直接回退到历史版本的节点,并且回退的这个版本,之后的提交都会被永久删除了
五.、忽略文件
当工作区下有一些文件不需要git管理的时候,在工作区下添加一个 .gitignore 文件,必须叫这个名字。文件中的语法如下:
匹配文件夹,用 dir_name / 比如忽略docs文件夹,就写 docs/匹配文件名,用 fileName,比如忽略f.txt,就写 f.txt支持通配符,比如所有的jar包都忽略,就写 *.jar需要注意的是,已经添加到版本库的文件,后加入到.gitignore,此时是无效的。必须删除版本库中该文件的信息才可以。
六. 同步到远程库
1、公私钥配置
打开cmd窗口,执行如下命令(邮箱换成自己注册的邮箱),其它不用填,连续三次回车,之后在系统的用户目录下会有一个.ssh的文件夹:
ssh-keygen -t rsa -C "[email protected]"
把id_rsa.pub中的内容复制到GitHub或者码云里:
github:
码云:
2、创建远程仓库
3、push同步到远程库
git remote add 名字 地址
是连接远程库的命令
git push -u 名字 分支
是推送本地代码到远程仓库
git remote add origin https://github.com/booy123/study.git
git push -u origin master
如果报错
fatal: remote origin already exists.
先删除远程 Git 仓库
git remote rm origin
查看仓库
git remote -v
可以查看远程信息:
4、删除本地库和远程库的关联
代码:git remote remove 名字
七、解决冲突
1、远程和本地冲突
fetch命令会把远端库同步到本地,但是不会和本地分支关联。
如果远程库不是空的,或者远程库中有本地没有的东西,比如在创建工程的时候选了README
远程仓库增加一个文件
此时同步 git push -u origin master
会出现问题,本地不能向远端提交数据:
方式一、通过git fetch origin master
同步下来,会产生新分支
git fetch origin master
:从远程的origin仓库的master分支下载代码到本地的origin master
接着用git merge origin/master
命令,把分支合并进来,merge的时候要注意解决冲突
还有一个命令是 git pull ,相当于fetch+merge的命令。pull和fetch的区别是,fetch不会直接进行分支合并,需要merge。而pull直接合并,可能会产生冲突,需要手动解决
方式2:执行以下语句
git pull origin master --allow-unrelated-histories
再推送就解决了
2、多人开发解决冲突
1)、修改不同文件
当团队中的人修改不同文件时,只要其中一个人提交到远程,另一个人肯定是提交失败的:
git push origin
提交时会出现如下冲突:
执行git fetch origin master
命令,再git merge origin/master
:wq
保存
git push origin
再提交就可以了
2)、修改相同文件
修改相同文件,有两种情况,一种是修改的区域相隔较远,一种是修改的区域相同或邻近,比如下面的情况就是邻近的情况
远程修改文件demo
本地修改后同步到远程库,无法提交
执行git fetch origin master
命令,再git merge origin/master
提示了冲突文件,需要手动编辑再提交就可以了
如果修改的区域相隔较远,一般merge的时候就会直接合并,不会出现冲突。
merge之后,确认冲突已解决,就可以继续提交了。
3)、修改文件名冲突
远程修改文件名
本地修改文件名并提交同步到远程库出现错误
冲突的一方去git pull 时提示文件重命名,并得到对方的文件
需要做的是rm不需要的文件,add需要的文件,最后commit
八、合并分支
把temp分支合并进master,先切换到master上,再执行git merge temp
九、其他操作
1、删除已上传的无关信息
删除远程仓库.idea 文件夹
git rm -r --cached .idea #--cached不会把本地的.idea删除
git commit -m 'delete .idea dir'
git push -u origin master
十、IDEA使用git
1、配置Git客户端
打开idea的settings,配置好的git地址
2、上传项目
初始化仓库
右键项目添加到暂存区
提交到版本库
同步到远程仓库
填写远程仓库用户名密码
提交成功
3、下载项目
4、解决冲突
如果两个人改了同一段代码,一个人先提交,另一个人就无法提交
选择Merge比较冲突
解决冲突
点击这两个箭头可以选择合并代码的位置,调整代码之后,再重新Push代码即可。
5、创建分支
创建新分支之后,提交代码,不会影响原分支
6、切换分支
切换分支之后,代码会变成该分支的代码
7、合并分支
把m1合并到master
先切换到master,保证当前分支是master,在需要合并的m1分支上点击merge,merge成功之后是在本地合并了,需要再push到远程仓库。在提交过程中如果遇到冲突需要解决冲突之后再Push
8、版本回退
在回退的文件进行修改,push解决冲突