分布式版本控制git学习笔记
git介绍
- 使用版本号区分(sha1 得出的hash值)
- 可浏览历史版本记录
- 可还原到历史指定版本
- 对比不同版本文件差异
SVN与GIT
1 SVN -集中式版本控制工具
缺点是远端服务器挂了就gg了,但优点就是容易操作
GIT – 分布式版本控制工具
远端有一个代码数据库,而在每个本地都有一个本地数据,每个机器都是分布式中的一个节点,两两机器之间也可以进行协作。所以 Git 支持离线工作,在本地可以进行很多操作,包括接下来将要重磅推出的分支功能。而 SVN 必须联网才能正常工作
git的缺点就是相对来说比较复杂
基本概念
在远端(Remote)创建裸仓库
裸仓库也就是不存放具体代码,即如果服务器泄漏了,入侵者也拿不到具体代码,方法如下
jyhlinux@ubuntu:~/mathlib$ git init --bare
同时,远端仓库别名为 origin
git中用到http 、ssh、git这三种协议。
其中ssh协议最重要,是一个验证授权的网络协议,并且通常使用ssh公钥放到git服务器上,每次登录用私钥来验证登录git服务器。
从远端克隆代码到本地仓库
在远端服务器(Ubuntu)和本地节点(Win)上都要要创建公私钥,方法是输入
ssh-keygen -t rsa
- 在远端服务器(Ubuntu上)到 ~ 目录下,进入
.ssh 文件夹,创建authorized_keys 文件:
touch ~/.ssh/authorized_keys
- 将本地节点上的公钥拷贝到 远端服务器上的 ~/.ssh/authorized_keys,本地节点上的公钥在
C:\Users\Administrator\.ssh\id_rsa.pub
- 然后在本地节点的某一你指定的位置打开git Bash,输入如下指令进行clone远端服务器上某个文件夹
git clone ssh://jyhlinux@192.168.200.153:/home/jyhlinux/mathlib
git clone ssh://主机名@IP地址:想要克隆的远端服器上的文件目录
最后结果: .git是隐藏文件夹
git中各阶段的示意图
注意到:svn中是没有暂存区(index)的
基本操作
- 暂存区:暂存多次修改,然后一次性提交到Repository。
git add 能把文件提交到暂存区,若没有提交到暂存区,则文件是未被追踪的状态(untracked):
提交到暂存区之后,可以看到暂存区中待commit的文件:
git push
将Repository(本地仓库)的文件推送到Remote(远端服务器);
其中远端服务器别名为 origin,分支默认为master:
git push origin master
git pull
将最新文件从Remote拉取到workspace中。
注意fetch和 pull区别,
- fetch只是把远端记录拉取到本地仓库(Repository);
- 而pull则是直接把改变的文件直接拉取到本地工作区(workspace)
- pull = fetch + merge
HEAD -> master中的HEAD
HEAD是一个指针,指向分支提交序列上最新一次提交。
git fetch
该指令只是拉取最近提交的信息出来到Repository,
逆向操作
index -> workspace(暂存区->工作区)
例如: 将sub.cc这个文件从暂存区回退到工作区
git restore -S sub.cc
结果:
本地仓库->暂存区(repository->index)或工作区(Workspace)或直接删除
注解:
- 从Repository退回到index,使用
git reset--soft ; - 从Repository退回到workspace,使用
git reset--mixed ; - 从Repository直接删除,使用
git reset --hard ;
例子
$ git reset --soft head^
#head表示最新的提交,^表示到上一次,上方代码表示回退到上一次commit的状态
#直接将repository中最新一次提交丢弃掉
$ git reset --hard head^
从本地工作区直接删除修改(workspace->null)
git checkout . #将当前目录下所有修改撤销,新添加的文件不会删除
本地仓库整理操作
复用上一次提交
下图表示本地分支高远端分支两个版本,我们在本地再次做了修改,想要合并到最上面的这个提交中去
本地修改之后git add,然后使用如下指令:
git commit --amend #进入文档中,x保存之后则完成复用最新提交
再次git log 查看状态,可以发现提交的信息没变,但是commit的序号改变了。
整理多次提交为一次提交
我们此时需要修改之前提交的 sub func
按如下操作:
git rebase -i
进入文档修改:
将sub func 所在行开头pick修改为e (edit),然后输入 : 再输入 x,保存退出。
vim中wq和x的区别:
在没有变更内容的时候,x不会修改文件最后修改时间,而wq会修改最后修改时间。
随后修改 sub.cc文件,并进行git add sub.cc 操作, 将修改添加到暂存区
然后输入git commit --amend ,我们复用feat:sub func 这次提交,故直接保存
然后再回到终端主界面,输入git rebase --continuegit rebase --continue ,完成整理多次提交。
将两次提交合并为一次提交
输入:git rebase -i ,将两次提交开头进行修改
保存之后,跳出另一个文档,让我们重新修改提交记录,修改为:
再使用git log 查看:
注意
只有当 【没有人基于你的分支进行开发的时候】,才能用git rebase 操作,因为从变基节点开始往后所有节点的commit id都会变化,可能导致其他人冲突。
分支操作
查看分支 git branch
创建分支
- git branch develop #只创建
- git checkout -b develop #创建并切换
切换分支
- git checkout #还有回退的功能
- git switch #后面版本增加的命令
合并分支(难点)
采用git merge解决冲突
- 解决冲突
- git add .
- git commit . -i -m “…”
有一个fix:merge master 这个提交,表明解决冲突
采用git rebase解决冲突(不推荐)
git rebase 用于没有其他分支依赖的情况下,进行 合并提交与 合并分支
- 解决冲突
- git add. 标记解决
- git rebase --continue;
git rebase master #将当前分支变基到master分支最新的提交位置
没有解决冲突的提交信息,给用户一种错觉,最新的提交是依赖于 feat:lshift func这次提交,这不正确。
注意:如何选择merge还是rebase
是否有其他人依赖我当前的分支?没有依赖我当前分支:可以用git rebase 有依赖我:必须用 git merge,因为git rebase变基之后 commit id发生变化
心得体会
git只要有个概念就好了,这种东西不用感觉也很容易忘记。对基本操作(add、commit、push、fetch…)逆向操作(git reset)和分支操作(git rebase、git rebase)大概原理有个印象应该可以了,未来到工作中再用用应该就熟悉了。
|