1、基本概念
1.1 仓库
什么是仓库呢?就是可以用git管理的一个目录,这个仓库里所有的文件的改动(增加/修改/删除)都由git跟踪
记录。也能通过git查看所有的记录,当然也能够通过git“还原”到某个记录点。
如何创建一个仓库呢?
- mkdir mysql_test(创建一个目录)
- cd mysql_test(进入这个目录)
- git init --bare(初始化一个空的仓库,bare选项指示该仓库为裸仓库)
远端仓库的别名一般是:origin
1.2 配置免密登录本地git服务器
1、在客户端机器对应的文件夹下,打开Git Bash Here
2、输入ssh-keygen -t rsa
,一路回车
3、此时会在c:/Users/zxm/.ssh/目录下生成id_rsa.pub和id_rsa文件,id_rsa.pub是公钥文件,id_rsa是私钥文件
4、在远端服务器上
cd ~
cd .ssh
vi authorized_keys
把id_rsa.pub文件的内容复制黏贴到authorized_keys
5、最后就可以免密从远端仓库拉取代码
格式:git clone ssh://远端服务器用户名@远端服务器IP:地址 重命名(可忽略)
git clone ssh://zxm@192.168.3.128:/home/zxm/share/gitLearn gitLearn-zxm
1.3 配置用户名和邮箱
当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。 这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改
1)局部
git config user.name zxm
git config user.email zxm@qq.com
配置位置查看
.git/config
2)全局
git config --global user.name zxm
git config --global user.email zxm@qq.com
配置位置查看
C:\User\zxm\.gitconfig
1.4 工作区域
- Workspace: 工作区,就是你平时存放项目代码的地方
- Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
- Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
- Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
1.5 工作流程
git的工作流程一般是这样的:
- 在工作目录中添加、修改文件;
- 将需要进行版本管理的文件add到暂存区域;
- 将暂存区域的文件commit到git仓库;
- 本地的修改push到远程仓库,如果失败则执行第5步
- git pull将远程仓库的修改拉取到本地,如果有冲突需要修改冲突。回到第三步
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)
1.6 文件状态
- Untracked: 未跟踪, 此文件在文件夹中,但并没有加入到git库,不参与版本控制, 通过git add 状态变为Staged。
- Unmodify: 文件已经入库且未修改, 即版本库中的文件快照内容与文件夹中完全一致,这种类型的文件有两种去处,如果它被修改, 而变为Modified,如果使用git rm移出版本库, 则成为Untracked文件。
- Modified:文件已修改,仅仅是修改,并没有进行其他的操作,这个文件也有两个去处,通过git add可进入暂存staged状态,使用git checkout 则丢弃修改,返回到unmodify状态, 这个git checkout即从库中取出文件,覆盖当前修改
- Staged:暂存状态,执行git commit则将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify状态。
2、基本操作
2.1 git add(暂存)
在仓库里刚新建的文件是不会被跟踪起来的,比如我们使用git status就能查看到文件的状态,需要使用git add才可以
基本用法:
git add <path>
通过git add <path>
的方式把path目录下的所有文件添加到git的暂存区,当然这些文件不包含已经被删除的文件。
示例:
$ git add . # 将所有修改添加到暂存区
$ git add *.cpp # 将以.cpp结尾的文件的所有修改添加到暂存区
$ git add hello* # 将所有以Hello开头的文件的修改添加到暂存区,例如: helloWorld.txt,hello.h,helloGit.md ...
$ git add hello?.* # 将以hello开头后面只有一位的文件提交到暂存区 例如:hello1.txt,helloA.cpp 如果是helloGit.txt和hello.cxx是不会被添加的。
git add
是把文件添加到暂存区,那如果想从暂存区删除呢?
1)从暂存区和工作区中删除 runoob.txt 文件
git rm runoob.txt
2)如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f。
强行从暂存区和工作区中删除修改后的 runoob.txt 文件:
git rm -f runoob.txt
3)如果想把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 --cached 选项即可:
git rm --cached runoob.txt
2.2 git commit(提交)
git add
只是把文件添加到暂存区而已,并没有真正跟踪起来,需要使用git commit
命令提交到仓库才能真正被git跟踪记录,git commit命令的用法如下:
$ git commit [file1] [file2] ... -m [message]
2.3 git push(推送)
git push 命令用于从将本地的分支版本上传到远程并合并。
命令格式如下:
git push <远程主机名> <本地分支名>:<远程分支名>
以下命令将本地的 master 分支推送到 origin 主机的 master 分支。
$ git push origin master
相等于:
$ git push origin master:master
2.4 git fetch 和 git pull(拉取)
git fetch
是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。
而git pull
则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。
1)git fetch 命令
$ git fetch <远程主机名> //这个命令将某个远程主机的更新全部取回本地
如果只想取回特定分支的更新,可以指定分支名:
$ git fetch <远程主机名> <分支名> //注意之间有空格
最常见的命令如取回origin 主机的master 分支:
$ git fetch origin master
2)git pull 命令
前面提到,git pull 的过程可以理解为:
git fetch origin master //从远程主机的master分支拉取最新内容
git merge FETCH_HEAD //将拉取下来的最新内容合并到当前所在的分支中
即将远程主机的某个分支的更新取回,并与本地指定的分支合并,完整格式可表示为:
$ git pull <远程主机名> <远程分支名>:<本地分支名>
如果远程分支是与当前分支合并,则冒号后面的部分可以省略:
$ git pull origin master
3、逆向操作
3.1 index --> workspace
git restore 命令用于恢复或撤销文件的更改。
如果你已经使用 git add 将文件添加到暂存区,但希望撤销这些更改,可以使用这个命令:
git restore --staged <file>
或者 git restore -S<file>
3.2 回退版本
git reset 命令用于回退版本,可以指定退回某一次提交的版本。
git reset 命令语法格式如下:
git reset [--soft | --mixed | --hard] [HEAD]
1)本地仓库 --> index:git reset --soft
2)本地仓库 --> workspace(默认):git reset --mixed
3)本地仓库 --> null:git reset --hard
如果想要撤销workspace区的修改,可以用
git checkout .
撤销当前目录所有修改
git checkout -- file
撤销当前file文件的修改
4、本地仓库整理
4.1 整理上一次提交
1)先提交两个文件 api.h 和 sub.cc 到仓库
git add .
git commit . -m "feat: sub func"
2)修改api.h,新加 mod.cc 文件,再提交到仓库
git add .
git commit . -m "feat: sub func"
3)git log 查看日志
4)现在,完善mod.cc文件,对其进行修改。希望相同功能多次提交复用上次提交信息,可以用git commit --amend
。具体来说,就是本次提交和上次提交合并一起。
4.2 整理多次提交
git commit --amend
是合并到上一个,如果是修改上上一个,比如sub.cc呢,可以用
git rebase -i h1 h2
,h1 和 h2 是提交的哈希值(或者可以是分支名),表示要重新整理的提交范围。如果忽略,代表的是最近两条提交记录。
1)若准备修改sub.cc,先输入git rebase -i
,按图修改指令
2)修改sub.cc
3)git add sub.cc
4)git commit --amend
5)git rebase --continue
另外,如果想合并 sub.cc 和 mod.cc两次提交记录,同样使用这个命令
1)git rebase -i
2)修改记录
3)git log
5、分支操作
5.1 查看分支
git branch
:查看本地分支
git branch -a
:查看本地和远端分支分支
5.2 创建、删除分支
git branch 分支名字
:创建分支
git checkout -b 分支名字
:创建并切换分支
切换分支:
1)git checkout 分支名字
2)git switch 分支名字
删除分支
1)git branch -d 分支名
2)git push origin -d 分支名
:删除远端分支
5.3 合并分支(git merge)
两个开发者zxm和guo,目前版本下有三个文件api.h、add.cc、sub.cc、mod.cc,其中api.h文件内容为
#pragma once
int add(int a, int b);
int sub(int a, int b);
int mod(int a, int b);
两个开发者都需要先拉取最新版本git pull
,在基于最新版本进行开发
1、对于guo开发者
1)修改api.h,并新增 mul.cc文件
#pragma once
int add(int a, int b);
int sub(int a, int b);
int mod(int a, int b);
int mul(int a, int b);
2)提交到远端仓库
git add .
git commit . -m "feat: mul func"
git push origin master
2、对于zxm开发者
有两个分支:master和develop
1)在develop分支,修改api.h文件,并新增div.cc文件
#pragma once
int add(int a, int b);
int sub(int a, int b);
int mod(int a, int b);
double div(double a, double b);
2)提交到本地仓库
git add .
git commit . -m "feat: div func"
3、现在zxm希望合并代码到主分支master
具体来说,guo基于远端仓库master最新版本开发,然后提交。zxm也基于远端仓库master最新版本,在develop分支开发,然后提交的代码,此时需要与master合并
1)对于zxm,切换到master分支,拉取最新的数据
git switch master
git pull
2)切换到develop,把master合并到develop
git switch develop
git merge master
此时会产生冲突
原因是:不同分支修改了同一个文件的同一行或相邻行
冲突解决原则是,既不要影响别人提交的功能,也不能破坏自己的功能。这个例子是要求保留mul和div功能。因此,解决如下
2.1)查看冲突文件:vi api.h
2.2)提交修改后的文件
git add .
git commit . -i -m "fix:merge master" # -i 是标识解决冲突
3)测试代码
4)代码测试通过,切换到master分支,把develop合并到master。测试如果ok,提交到远端
git switch master
git merge develop
git push origin master