1.git简介
git是使用C语言编写的分布式版本控制系统
集中式VS分布式
SVN集中式 : 需要一台服务器充当中央服务器 缺点:需要联网才能工作,一旦中央服务器出现问题,会影响整体的效率
git分布式: 每个电脑都相当于一个完整的版本库
git常用命令:
-
创建版本库
创建完成后目录下面会有一个.git的文件,这个目录是用来管理git仓库的,不要乱动。该目录默认是隐藏的 ls -ah可以看见
1. mkdir learngit 创建一个文件夹
2. cd learngit 进入文件夹
3. git init init初始化为git仓库
-
把文件添加到版本库
1. 新建的readme.txt文件放到建的仓库目录下,子目录也行。
2. git add readme.txt 告诉git把文件添加到仓库
3. git commit -m "添加了readme.txt文件" 告诉git把文件提交到了仓库
需要明确:所有的版本控制系统都可以追踪文本文件的变化,比如TXT文件,网页,程序代码等。
而二进制文件例如图片、视频等(Microsoft的word格式也是二进制的格式)可以由版本控制工具
管理,但是无法追踪到发生了什么变化。不要使用win的记事本编辑文件,因为可能乱码。
提交文件同样有两个步骤: 1.git add <file> 先添加文件 2. git commit -m "修改内容" 然后提交
-
时光机穿梭(版本回退)
1. git status 可以时刻掌握仓库当前的状态,如果显示是红色表示还没有提交到暂存区,如果是绿色表
示已经提交到了暂存区
2. git diff <file> 可以查看文件上次的修改内容
3. git log 显示由最新到最远的提交日志
4. git log --pretty=oneline git log输出信息太复杂 可以使用此命令信息简化
5. git reset --hard HEAD^ 回退上一个版本,上上个版本是git reset --hard HEAD^^,当然往上
100版本可以简写为HEAD~100
6. git reset --hard <版本号> 回退指定版本号的版本(其中版本号没必要写全,但是也不能写很少,要
保证根据上面的只能找到唯一的一个版本)。如果发现回退后后悔了想再 回到最初的版本,只要能找到最初的版本号,也可以使用该命令,再返 回去
7. git reflog 用来记录每一次的提交/回退等等版本变化的命令。如果git reset -- hard HEAD^回退
到了先前的版本,如果想再穿回来的话可以使用该命令找到最新版本提交时候的版本ID,然 后使用git reset --hard <版本号> 再穿越回去。
git的版本号是使用SHA1计算出来的非常大的数字,因为git是分布式的版本控制系统,所以为了防止重复。
穿梭前,用git log 命令查看提交的历史,以便确定要回退到哪个版本,要重返未来,git reflog查看命令以确定要回到未来哪个版本
-
工作区和暂存区
工作区:就是再电脑里面能看到的目录,例如我们创建版本库后新建的文件夹就是工作区,现在工作区修改然后git add 提交到暂存区
版本库:.git目录就是我们的Git的版本库,git的版本库中存放了很多东西,其中最重要的就是成为stage(或者叫index)的暂存区。在提交文件的时候我们需要先执行 git add <file> 命令,此命令就是把文件先提交到暂存区里面,然后我们执行命令 git commit -m "message",是把暂存区的所作的修改都提交到分支上面。如果一旦提交后,并且没有在做其他的修改那么我们的工作区就是干净的。使用git status命令查看就会提示 working tree clean
管理修改:git跟踪管理的是修改而不是文件,就是说文件修改了并且执行命令 git add 后,然后git commit 才能提交的了,也就是所有的文件必须先git add 添加到暂存区后才能通过命令 git commit 提交到版本库。即git commit命令是只能提交暂存区的文件到版本库。
-
撤销修改
1. git checkout -- <file> 把文件在工作区的修改全部撤销掉
分两种情况
a. 文件修改了但是还没有被放到暂存区,现在撤销修改就是回到和版本库一模一样的状态
b. 文件已经被添加到暂存区后,又做了修改,现在撤销修改就是回到添加到暂存区后的状态
总结:就是让这个文件回到最近一次 git add或者git commit的状态
2. git reset HEAD <file> 把暂存区的修改撤销掉并重新放回工作区。然后在使用 git check -- <file>命令把工作区的修改全部撤销掉
总结:git checkout 和 git reset HEAD <file> 的区别,一个是把文件从工作区撤回,一个是把文件在暂存区的修改撤销掉重新在放回到工作区中。
-
删除文件
从版本库中删除文件分两步
1.先执行命令 git rm <file> 从版本库中删除文件 ,然后git commit -m "remove file" 提交
如果不小心 rm -rf <file> 删除文件了,如果想再次找回,可以使用 git checkout -- <file> 命令将误删除的文件恢复到最新版本
2. 如果真的已经删除掉了,可以使用git reflog命令查看,然后使用git reset --hard <版本号> 回退到这个版本,文件就能回来啦!
-
git的远程仓库
Git是一个分布式版本控制系统,在实际情况中,通常是找一台电脑从但服务器的角色,然后其他人从这个服务器上面克隆一份代码到自己的服务器
仓库里面,也可以从服务器中拉取别人的提交。
以GitHub当成远程仓库为例
1. 创建SSH的key。在用户的主目录下,看看有没有.ssh目录,里面又id_rsa和id_rsa.pub两个文件,如果有这两个文件则跳过第一步。这两个
是SSH Key的密钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心的告诉别人。如果没有打开Shell(windows下打开Git Bash)
创建SSH Key
ssh-keygen -t rsa -C "XXXX@163.com" 换成自己的邮箱一路enter
2. 创建成功,创建成功会提示你的公钥和私钥保存的位置
登陆github ,打开"Account settings"的 "SSH Key"界面,然后"Add SSH Key"填写任意的Title,然后在Key的文本框里面粘贴上自己的公钥id_rsa.pub里面的内容
GitHub需要SSH Key,识别出内容的确是你推送的,而且可以添加多个Key。使多个终端都可以提交内容。github上面的内容都是免费托管,任何人都可以看到,想变成私有的一是掏钱让github官方给搞成私有的,另一个就是自己搭建自己的git服务器。
-
添加远程库
在github上面创建仓库后,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库
1. 在本地的仓库里面使用多种关联方式 git支持SSH协议和HTTPS协议
a. 使用HTTPS的方式 推送到远程服务器时候需要输入github的账号和密码,不需要配置上面的SSH方式
git remote add origin https://github.com/Panic-sheep/learngit.git 其中Panic-sheep为github的账户名。把本地的仓库和GitHub上面的远程仓库关联起来
b. Use SSH 使用SSH方式
git remote add origin git@github.com:Panic-sheep/learngit.git 使用SSH方式关联,这种方式需要配置SSH
注意:如果已经使用了一种方式关联了远程库,再使用另一种方式关联时会提示 remote origin already exists. 所以说只能使用一个。如果说已经关联了又想使用另一种
方式 可以先执行git remote remove origin 删除远程仓库,然后再使用另一种方式进行关联
2. 推送本地库的内容到远程库中
git push -u origin master
把本地库的内容推送到远程使用git push命令,实际上是把当前分支master推送到远程。由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。后面只需要
git push origin master 就可以把本地仓库的内容推送到自己github上面。
-
从远程库克隆
git clone git@github.com:Panic-sheep/learngittwo.git git clone克隆远程仓库到本地
注意:上面的添加远程仓库以及克隆完仓库后,需要提交的都必须在相应的仓库里面执行命令 git push origin master
-
分支管理
1. git branch <name> 创建分支
2. git checkout <name> 切换分支 上面两条命令可以合成一条命令 git checkout -b <name>
3. git branch 列出所有的分支,且当前分支前会有一个*号
4. git merge <name> 合并指定分支到当前分支
5. git branch -d <name> 删除分支,且如果git branch在当前分支上,则不允许删除。需要先checkout到master分支上在执行删除命令。
6. git branch -D <name> 如果要丢弃一个没有被合并过的分支,使用该命令
另外:切换分支也可以用switch, 创建+切换分支 git switch -c <name> 切换分支:git switch <name>。但是switch命令是在2.23版本后才又的,先前的旧版本不能使用,想使用的话需要升级。git --version 查看当前的git版本升级到最新版本 :2.17.1前的版本使用命令 git update , 2.17.1后的版本使用命令 git update-git-for-windows
-
分支冲突解决
在不同分支上修改了相同的文件,会造成merge合并时候失败,并且在合并失败的文件上又标注冲突的地方。这些冲突需要我们手动解决掉。手动编辑为我们希望的内容。
解决后,在重新add和commit。使用命令git log --graph --pretty=oneline --abbrev-commit 查看分支的合并情况。
-
分支合并策略
合并分支时,如果可能的话Git会使用fast forward模式,快速指针的指向。但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,
Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
在实际的开发中,应该都在dev分支上检出分支干活,并把修改都合并到dev分支上,然后当dev稳定后,在把dev的修改合并到master分支上。
-
bug分支管理
在实际开发中,可能我们需要先紧急处理一个bug,git提供了一个stash的功能,可以把当前的工作现场储存起来,可以等修改完成后再重新恢复工作
1. git stash 把当前现场的工作隐藏起来
2. git stash apply 恢复到现场
3. git stash drop 删除暂存的东西
4. git stash pop 恢复现场的同时把stash内容也删除掉
5. git stash list 查看暂存的内容
6. git cherry-pick <版本号> 复制一个指定的提交到当前的版本
总结:当多次的修改并git stash 后,使用 git stash list 可以查看有多个暂存的内容,这个时候 git stash apply stash@{0},其中stash@{0}即list看到的内容的前缀上面的内容,这样可以恢复到指定的stash。当再某个分支上修改了bug后那么再这个分支先前的版本上面开出去的分支也会有这个bug,我们就可以使用 git cherry-pick <版本号> 复制指定的提交到当前版本
-
多人协作
当从远程仓库克隆时,实际上是把Git把本地的master分支和远程的master分支对应起来,git默认远程仓库名为origin
1. git remote 查看远程库信息
2. git remote -v 查看远程库信息并显示抓取地址推送地址等
3. git push origin <name> 把分支<name>上的本地提交都推送名字为origin的远程库
从远程库上克隆时候默认只能看到本地的master分支,如果想要在dev分支上开发就需要创建一个远程的origin的dev分支到本地,使用命令: git checkout -b dev origin/dev 创建一个dev分支并且与远程库origin的dev分支关联,然后就可以在上面正常开发提交了。
直接记录下:
1. 先用命令 git push origin <name> 推送再本地分支上的修改到远程仓库
2. 如果推送失败,则可能时远程的分支比本地的要新,需要先用 git pull 命令把远程的分支上面内容抓取下来,在本地合并后再push
3. 如果合并有冲突,就本地解决冲突,然后本地提交,解决完冲突或者再没有冲突后,再用 git push origin <name> 推送到远程库
入果 git pull 提示 no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令 git branch --set-upstream-to <branch-name> origin/<branch-name> 先创建链接(在比较老一点的git版本中 命令为 git branch --set-upstream-to=origin/<branch-name> <branch-name> ) ,然后再git pull下来。在提交前最好先git pull一下
git rebase rebase操作可以把本地未push的分叉提交历史整理成直线;rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比