Git使用
一、git与svn区别
svn集中到中央服务器的,你手中只有版本一小部分版本,而git是分布式的,及每个人的都可以是一个版本中心,所以又叫去中心化,当你需要和别人共享版本时,通过push 和 pull 就可以和git服务器同步,这个服务器可以是任意一台包含版本仓库的服务器。可以类比银行和区块链,比特币的区块链设计就类似git,人手一份全账本,只是用p2p全网同步,而git通常搞个中心化服务来同步,svn像银行,完整账本只有银行有,作为终端节点可以向银行查询账本,但如果某一天银行没了,整个完整账本就没了。
二、git安装与配置
-
在Windows上使用Git,可以从Git官网直接下载安装程序,然后按默认选项安装即可。
-
配置邮箱和用户名
#初始化git 的用户名和邮箱, 退出配置查看 , 按Q键 git config --global user.name MilesWangZhen #设置用户名 git config --global user.mail a@miles #设置默认邮箱 git config --list #查看配置
三、创建版本库并提交
-
新建一个gittest目录,目录建议避免中文,通过
git init
命令把这个目录变成Git可管理的仓库git init Initialized empty Git repository in C:/Users/chenfu/Desktop/test/gittest/.git/
-
把文件添加到仓库
# 把未跟踪的代码或文件,加入跟踪列表 git add xxx
git add 语法:
- 添加多个文件:git add a.java b.java
- 添加目录下所有文件:git add java
- 添加当前目录下的所有文件:git add .
-
git status
查看文件是否添加成功,绿色表示成功 -
将文件提交到本地仓库中
git commit -m "commit the Java folder"
四、版本回退
以回退到上一个版本为例,会有三种方式
当我提交了一个空白的readme文件,使用了 git commit -m "commit the readme file"
命令,我想回到只有java文件的版本,则可以使用以下三种方式
-
回退到上一个版本,版本就回到了
commit the java folder
版本,此时仓库中就没有readme文件#回滚到上一个版本 git reset --hard HEAD^ HEAD is now at 77c7dcb commit the java folder
-
或者我通过查看提交日志的方式,直接回滚到制定版本号
# 查看日志(输入q即可退出) git log # 回归到指定的版本,版本号最少4位 git reset --hard 77c7dcb
-
查看所有操作日志然后可以看到之前版本回退记录
# 查看操作日志 git reflog # 回归到指定的版本,版本号最少4位 git reset --hard 77c7dcb
从这可以看到之前的几次版本操作日志以及提交日志,以及当前处于最新的版本。
-
总结
-
如果确定回滚的是上一个版本,可以使用第一种方式
-
回到指定版本号可以使用第二种方式确认版本号信息,然后回滚
-
第三种方式适用于要回滚到后一版本的情况,因为
git log
只能查看当前和之前的版本
-
五、工作区,缓存区和分支
- 工作区有一个隐藏目录
.git
是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
git add之后,就从工作区到了暂存区,commit之后就把暂存区的内容提交到了当前分支中,分支的具体作用后面会提到。
-
移除add或commit的文件
# 一般用于移除暂存区中的文件,文件语法和add一致 git rm -r --cached xxx
这个命令将暂存区的内容全部清楚,即已经add过的文件取消跟踪,包括已经commit过的文件。
并且再次提交时如果没有将意外取消跟踪的文件重新add,文件将从版本库中移除,所以此命令最好谨慎操作,并且指定需要取消的文件或文件夹。
-
撤销修改
# 通过checkout命令撤销,文件语法和add一致 git checkout -- xxx
- 当我已经将内容add时,通过checkout命令获取到是暂存区最新的内容
- 当我已经将内容commit时,通过checkout命令获取到是当前分支中最新的内容
-
删除文件
删除已经commit的文件,再通过commit命令,将版本库中内容同步删除
#注意前面没有git,文件语法和add一致 rm xxx # 提交删除操作 commit -m "delete xxx file"
六、分支的理解
分支通俗理解

最开始的分支图

-
创建并切换分支
git checkout -b dev #等价于 git branch dev git checkout dev #将本地分支push到远程 git push origin dev
创建完分支之后

-
查看所有分支
# 当前HEAD指向的dev分支 git branch
-
删除readme文件
dev删除readme文件之后的分支结构, 此时的master还没有删除,当前HEAD指向的dev分支
-
合并分支
#切换会master分支 git checkout master #合并分支 git merge dev
合并之后的分支结构图,当前HEAD指向的master分支

-
删除分支
git branch -d dev git branch -D dev #强制删除 git push origin --delete dev #删除远程分支
当分支合并完成之后可以删除,因为分支创建只是相当于添加了一个指针,所以删除可以比较随意
-
查看分支结构图
git log --graph
-
创建分支并关联到远程分支
git checkout -b dev origin/dev
七、解决冲突
git中常见冲突会有两种形式
7.1 第一种
本地版本落后于远程版本,然后pull时产生冲突
这种情形一般是你的同事改了a.java文件并提交到远程,然后你也改了a.java文件,然后你想提交时,发现你的本地版本落后于远程版本,系统提示需要pull一下,这时,由于远程a.java和你本地a.java不一致导致冲突,所以只能手动解决问题。
如你同事提交在a.java中提交的内容是
// 在master分支中测试冲突解决
你修改a.java的内容是
// 在master分支中测试冲突解决
// 冲突问题已经解决
当你执行git push
时,提示了错误,大致意思是让你pull一下最新版本,然后你执行了git pull
命令冲突就产生了
可以通过git status
查看冲突的文件
<<<<<<< HEAD
// 冲突问题已经解决
=======
>>>>>>> 28fdb4d275dc4404e4addb78a356f32143195e71
// 在master分支中测试冲突解决
此时,你的文件已经和版本远程版本一致了,所以你可以将代码改成你想要的,比如优化一下
// 在master分支中测试冲突解决
// 冲突问题已经解决
先add,再commit,最后再push就行了
7.2 第二种
一般是自己本地分支之间的冲突
如当你本地feature分支修改了b.java文件,然后切换到master分支,又修改了b.java文件,然后merge分支feature分支时产生冲突
如通过git checkout -b feature
创建并切换到feature分支中,b.java提交的内容是
//测试在feature中解决冲突
通过git checkout master
切换到master分支,b.java提交的内容是
//测试在master中解决冲突
此时通过git merge feature
合并分支时,就产生冲突,git status
可以查看到冲突的文件
<<<<<<< HEAD
//测试在master中解决冲突
=======
//测试在feature中解决冲突
>>>>>>> feature
所以可以根据自己的需求修改文件,如改成
//测试在git中解决冲突
先add,再commit,冲突就解决了
八、远程仓库
远程git仓库推荐使用gitee,github速度不是很快,创建一个gittest仓库。
8.1 关联仓库
提供了两种方式关联到仓库,可以设置当前git账户信息
git config --global user.name "Cash_Hunter"
git config --global user.email "214556924@qq.com"
- 第一种是本地已经有了仓库,如前面执行过
git init
的文件夹,通过git remote
可以关联,关联之后执行push命令
#origin是版本库的名字,可以取任意名字,可以理解成远程仓库的别名
git remote add origin https://gitee.com/mileswangz/gittest.git
#第一次推送需要使用-u,可以将本地的master分支和远程的关联起来
git push -u origin master
- 另一种是远程仓库中已经有内容了,可以从远程仓库克隆下来,再推送
git clone https://gitee.com/mileswangz/gittest.git
#修改并提交后,执行git push就行
git push
8.2 查看,修改关联仓库
-
查看远程库信息
$ git remote -v origin https://gitee.com/mileswangz/gittest.git (fetch) origin https://gitee.com/mileswangz/gittest.git (push)
-
删除关联关系,指定远程仓库名即可,这里只是删除关联关系,并不会删除远程仓库
git remote rm origin
九、常见错误
9.1 Permission denied
-
问题描述
第一次push 时,输入了正确密码,提示 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
fatal: Could not read from remote repository.
-
问题原因
问题根源是ssh的问题,由于使用SSH连接,第一次需要配置SSH公钥和密钥
-
解决办法
在任意目录下执行 ssh-keygen -t rsa -C"your_email@example.com",git会在windows的本地用户目录下的 ./ssh 目录下
生成密钥和公钥 id_rsa 或 id_rsa.pub 两个文件,如
C:\Users\你的电脑用户名\.ssh
,然后使用公钥id_rsa.pub在git远程中生成密钥 -
注意事项
如果公司的ssh端口不是22,还需要额外在
.ssh
目录下添加config配置文件,配置具体的端口# gitee Host #git服务ip地址 Port #对应的端口 PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa User #用户名
9.2 文件资源被占用
具体问题已经不好重现了,所以网上找了张图
-
问题描述
Another git process seems to be running in this repository, e.g.
an editor opened by ‘git commit’. Please make sure all processesare terminated then try again.
-
问题原因
Git原则上是支持多进程同步操作资源的,但是如果出现了崩溃,就会出现这样那样的问题,建议同一时间还是只打开一个Git进程进行版本管理比较好。
-
解决办法
很简单,删除index.lock就行
9.3 master分支受保护
-
问题描述
向master推送时,提示这个错
Gitlab: You are not allowed to push code to protected branches on this project.
-
问题原因
master分支默认受保护的,及不能直接push
-
解决办法
理论上是可以直接将master分支改成unprotected,但是还是建议直接推送到其他分支,然后由项目管理员去merge
十、参考链接
文章部分参考廖雪峰老师的git教程
十一、补充
11.1 stash状态暂存
git stash这个命令可以将当前的工作状态保存到git栈,在需要的时候再恢复。
当在一个分支的开发工作未完成,却又要切换到另外一个分支进行开发的时候,可以先将自己写好的代码,储存到 git 栈,进行另外一个分支的代码开发。这时候 git stash命令就派上用场了!
git stash #可以多次使用,每次使用,都会生成stash@{num},num是编号
git stash save '注释' #可以添加备注,和git stash无差别
git stash pop #默认恢复git栈中最新的一个stash@{num},该命令会将堆栈中最新保存的内容删除
git stash list #查看当前stash的所有内容
git stash apply stash@{num} #将堆栈中的内容恢复到当前分支下。这个命令不同于 git stash pop。该命令不会将内容从对堆栈中删除
git stash drop stash@{num} #从堆栈中移除指定的stash
git stash clear #移除全部的stash