1. 创建一个git仓库(仓库又叫做版本库):
仓库有两种:普通仓库和裸仓库
git init 仓库名
如git init a
此时会创建一个a目录,里面有一个.git的隐藏目录
这个目录里面有一些文件和目录
git init --bare 仓库名
如 git init --bare a
创建一个裸仓库a,里面没有.git目录,但是会有.git目录的文件
如果是一个已有的目录,如何将这个目录纳入git的管理:
首先进入这个目录 cd .....
然后 git init 即可
2.克隆一个已有仓库
git clone 已有仓库名 重命名的仓库名
如 git clone a a1
当然你也可以克隆一个远程的仓库。
项目目录有3个区域
工作区,即我们编辑代码的地方
历史提交(历史仓库),是commit指针指向的tree
暂存区,是一个虚拟的tree
暂存区是连接工作区和历史提交的中间区域,工作区编辑好的代码要先提交到暂存区,然后才能提交到历史提交中;
而要想从历史仓库中获取文件到工作区也要经过暂存区
PS:在git bash的黑盒子里面,可以使用Linux的所有命令,即使你是在windows的系统下!
3.将目录推送到远程仓库(github) 和 将远程仓库拉取到本地
a.注册一个GitHub账号;
b.建立本用户(我的电脑)和GitHub的关联SSH Key(如果之前建立过则无需建立):
打开git bash黑盒子,输入:
ssh-keygen -t rsa -C "你的邮箱"
然后一路回车;
完成后会发现,C盘的Administrator用户目录中有.ssh目录(隐藏文件),里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,id_rsa.pub是公钥
c.在github添加公钥
登陆GitHub,在右上角的小按钮打开“settings”,进入“SSH Keys”页面:
然后,点“New SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容
可以添加多个SSH key,因为你可能在多台电脑上都有git;公司的电脑可以建一个和GitHub的关联,我自己的电脑也建立一个和GitHub的关联;这样就有两个SSH key了
接下来我们可以 将本地仓库同步到远程仓库 和 将远程仓库同步到本地仓库
d.将本地仓库同步到远程仓库
首先,创建一个新的远程仓库(新的项目),项目的名字是redis(里面放着一些有关redis的代码实例和笔记)
然后,建立本地项目目录redis与远程仓库redis的关联
cd redis # 进入本地的redis目录
git remote add origin git@github.com:自己用户名/redis.git # 和远程redis目录建立关联
# 或者git remote add origin https://github.com/自己用户名/redis.git
然后,将本地的redis项目推送到刚创建的GitHub的redis远程仓库中
git add . # 将redis目录下所有文件添加到暂存区
git commit -m "First commit" # 将暂存区的内容提交到本地git仓库
git push -u origin master # 把本地库的内容推送到远程库上
# master是当前分支;第一次推送时,由于远程仓库是空的,所以要加上-u参数;之后推送到远程库就可以不用加-u
e.将远程仓库同步到本地仓库
下载远程的redis项目:
git clone git@github.com:我的用户名/redis.git
将远程的redis项目代码同步到本地的redis目录(就是将远程的代码替换掉本地的代码)
git pull origin master:master
有一点会导致git pull 远程同步到本地出现错误:如果之前你在本地的工作区做了暂存(add),但是还没有提交(commit)的情况,此时你要么清空暂存,要么做出提交才能git pull成功。
查看你已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出你指定的每一个远程服务器的简写
git remote -v 是查看远程地址的详情
4.git的提交( commit )
git的工作区,暂存区和本地仓库:工作区就是我们本地的文件内容(也就是我们写代码的地方),暂存区是用git add 将文件暂存的地方,本地仓库是用git commit 将文件提交到的地方。
git工作的一个大致流程如下:
在工作区修改代码后,使用git add 将修改了的文件暂存到暂存区,在真正提交之前,每一次修改代码都要暂存一次,最后使用git commit将文件提交到本地的git仓库。
如下:
git init a
touch 1.txt #创建1.txt文件
touch 2.txt
touch 3.txt
git add 1.txt 2.txt # 将这两个文件添加到暂存区中,但此时这两个文件还没提交
git status # 查看a目录下的文件的提交状态
git commit -m "初次提交" # 将已添加到了暂存区的文件提交到本地仓库,这里是将1.txt和2.txt提交到历史仓库;3.txt由于没有添加到暂存区,所以没有提交到历史仓库
git status //此时再查看,发现暂存区已经没有了1.txt和2.txt了
如何删除暂存区中的文件
git rm 1.txt # 删掉工作区和暂存区下的1.txt
git rm --cache 1.txt # 只删除暂存区中的1.txt
git rm --cache -r . # 删除暂存区中的所有文件(清空暂存区)
如何排除指定的目录或者文件不暂存
在根目录创建一个 .gitignore 文件,文件里面填写目录或者文件路径即可:
可以写相对路径或者绝对路径。
查看工作区文件较上一次提交的改动内容
git diff 1.txt
查看提交的历史记录
git add readme.txt
git commit -m "add readme.txt"
git log
# 显示结果
# >>> commit a92311afb7329b5bc7a09d41d6cb906f0aac1d97 (HEAD -> master)
# Author: zbp <git@zbp.com>
# Date: Sun Nov 25 18:21:23 2018 +0800
# add readme.txt
每一次commit提交都会有一个版本号,a92311afb7329b5bc7a09d41d6cb906f0aac1d97是这个提交的版本号,HEAD -> master 指的是这次提交的是master分支。add readme.txt是提交时的描述。
commit版本号
HEAD表示当前版本(也是当前所处于的commit指针)
比如我一共做了两次提交:
vim readme.txt #添加了一行readme
git add readme
git commit -m "First Commit" #做出第一次提交
vim readme.txt #添加第二行readme readme
git add readme
git commit -m "Second commit" #做出第二次提交
git log
# 结果如下
# commit 13e9c9dd3ab1d1b5e575c1522bf2e24bb7704790 (HEAD -> master)
# Author: github-zbp <1640632344@qq.com>
# Date: Thu Oct 8 11:50:03 2020 +0800
#
# Second commit
#
# commit 0c2225b3bd6c7a221c968966eadb150c2dd7a51f (origin/master)
# Author: github-zbp <1640632344@qq.com>
# Date: Thu Oct 8 11:08:31 2020 +0800
#
# First Commit
因为做了两次提交,所以此时会有两个指针,他们分别对应两个版本号
我现在处于的版本是13e9c9dd3ab1d1b5e575c1522bf2e24bb7704790
版本回退
如果我做了一次错误的修改,并且做了提交,此时我希望能够回到上一次提交的状态可以使用版本回退
git reset --hard 版本号 # 可以通过git log查看历史版本号
这样的话,工作区的内容就会回到指定版本库的状态的内容。
一旦回滚到了从前的版本号,就无法再回到最新的版本号,如果真的想回到最新的版本号也可以,此时要这样:
git reflog # 查看最新版本号历史记录
git reset --hard (最新的版本号)
其他的回滚方式:
git reset 版本号 # 回滚到工作区,暂存区的内容不保留(就是你浏览器能看到回滚的代码,但是你git status看不到你回滚的代码)
git reset --soft 版本号 # 回滚到暂存区
回滚远程分支:
# 只需要回滚了远程分支之后再执行下面的命令即可
git push origin HEAD --force
代码的分支间迁移
如果你在分支A提交了一个版本X,之后想在分支B做出和版本X的内容一样的改动,此时可以使用cherry-pick命令。
# 在分支B下执行下面的代码
git cherry-pick 版本X的版本号
5. git分支管理
git分支的用途:比如一个项目大家分工合作,员工A只负责完成控制器的编写,B只负责完成模型的编写;
如果A完成了20%的时候将本地仓库上传到了远程仓库;此时B在自己的电脑上也完成15%的工作,于是也上传到远程仓库;但是B只负责完成模型的编写,所以B的项目中的控制器部分是空的,这样一上传,就把A工作的部分给干掉了...
分支就是为了解决团队协作开发代码这个问题的!
创建分支和切换分支
git checkout -b 分支名 # 创建一个分支并切换到新分支,相当于 git branch 加上 git checkout
git branch 分支名 # 创建一个分支
git checkout 分支名 # 切换到一个分支
git branch -a # 查看当前所有分支,包括远程的(remote开头的就是远程分支)和本地的
合并分支
项目的master分支是主干分支,一般我们的其他分支会合并到主干分支中。
git checkout master # 先切换到主分支
git merge 分支A # 将分支A的内容合并到主分支
PS:这里是在本地进行合并分支,也就是说是将我本地的分支A合并到master分支。在真实工作中,都是将分支A给push到远程后,在远程进行合并到master分支,当然一般来说本人是没有远程合并主分支的权限,而是由我们的导师审核代码通过之后,由导师进行合并主分支。
在远程进行合并分支就不是用命令,而是点击一个按钮就可以搞定。
PS:在切换分支之前,如果你现在所在的分支做出了改动而没有提交,那么是无法切换分支成功的
查看合并分支图
git log --graph
合并冲突
以下情况会出现合并冲突:
master分支上创建了新分支A,工作人员1在分支A修改了脚本M的代码(并且commit了),工作人员2在master分支上修改了脚本M的相同位置的代码(并且commit),之后工作人员1将分支A合并到master,此时会造成冲突
或者
master分支上创建了新分支A和分支B,工作人员1在分支A修改了脚本M的代码,工作人员2在分支B上修改了脚本M的相同位置的代码,之后工作人员1将分支A合并到master,此时合并成功,工作人员2再将分支B合并到分支A,此时会造成冲突
如果是修改的不同文件或者相同文件不同位置,就不会出现这种冲突。
发生冲突的情况下合并也会成功,但是会在有冲突的内容中用
<<<<<<<<<<<<<<HEAD
>>>>>>>>>>>>
分开
如果发生了冲突,可以在合并之后手动解决冲突(合并后手动修改代码,决定是留下工作人员1还是工作人员2的代码)
更新本地分支名
git remote update origin
作用: 更新本地分支名(使之与远程分支的分支名同步)
场景: 远程新建分支之后,本地看不到最新分支;远程仓库存在,本地项目存在但为建立仓库,在本地执行git init后,再执行git checkout -b 本地分支名 origin/远程分支名 拉取分支失败,提示:
fatal: 不能同时更新路径并切换到分支'feature/erp-v6.2.2.k11'。
您是想要检出 'origin/feature/erp-v6.2.2.k11' 但其未能解析为提交么?
此时需要更新本地分支名。
6.git的配置
1.git最基本的配置:
进入git bash,然后输入以下命令:
git config --global user.name zbp
git config --global user.email wenzhangxiang@yeah.com
申明一下用户是谁即可;
2.git的3个配置级别:
git config --system ...
git config --global ...
git config --local ...
从优先级而言local>global>system;
local针对的是当前的仓库
global针对的是当前的用户
如何查看git的手册:
git 命令名称 --help
git help 命令名称
都可以
配置的增删改查
增:
git config 配置级别 键 值
如 git config --global user.name zbp
git config 配置级别 --add 键 值
如 git config --global --add user.name zbp
使用--add表示一个键名可以存多个值;
查:
git config 键
git config user.name
git config --get 键
git config --get user.name
git config --list 配置级别
查看该配置级别下所有的变量
如:git config --list --global
删:
git config --global --unset 键 [值]
如果这个键有一个值,那么git config --global --unset 键就行
如果这个键有多个值,而你只想删里面的一个值,那么就要:git config --global --unset 键 值
改:
同增的命令
给git常用命令起别名:
git config --global alias.别名 命令名
如:git config --global alias.ci commit
还可以给命令的某个参数起别名
git config --global alias.lol "log --oneline"