最简单的版本控制是什么
复制整个项目目录的方式并附加时间后缀
从 本地控制系统——RCS
到 集中化版本控制(svn)
再到 分布式版本控制系统(git)
例如svn的很多系统,保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异
Git则是在保存时,对当时的全部文件制作一个快照并保存这个快照的索引
产生的优势
这三种状态也对应了三个工作区域概念:Git 仓库、工作目录以及暂存区域
Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
工作目录是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。
对应的git生命周期
安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址
git config --global user.name "BugMaker"
git config --global user.email "BugMaker@example.com"
这样以后每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改
# 添加文件至暂存区
git add file
# 添加所有文件至暂存区
git add .
# 移除暂存区的文件并删除目录
git rm file
# 移除暂存区的文件但保留文件
git rm --cached file
# 文件改名
git mv file_from file_to
# 提交暂存区更改
git commit
# 以-m参数的内容进行提交
git commit -m "update file"
# 跳过暂存区直接提交
git commit -a -m "update"
# 查看git状态
git status
status的几种状态
# 查看文件修改
git diff
# 查看提交历史
git log
# 附带参数
# -p 附带文件修改记录
# 通常搭配 -num 限制显示数量
git log -p -2
# 修正提交记录(可以补充文件)
(git add forgotten_file)
git commit --amend
# 撤销文件
git reset
危险操作 git reset --hard 会丢失当前所有所做的更改!
# 查看远程仓库
git remote -v
# 从远程仓库中拉取
git fetch [remote-name]
# 向远程仓库推送
git push [remote-name] [branch-name]
对于已经设定了远程跟踪的分支,git pull命令来自动的抓取然后合并远程分支到当前分支
git pull => git fetch && git merge
git tag打标签操作,有兴趣的话可以访问git文档进行阅读
回顾: git保存的是什么?
文件快照
git提交的是什么?
一个包含三部分的对象:
我们进行了多次提交后,会利用里面的指针进行索引
那么回到最初的问题,git的分支的本质是什么
git的分支就是指向提交对象的指针:
Git 的默认分支名字是 master 在多次提交操作之后,master 分支指向最后那个提交对象
# 新建分支
git branch testing
此时我们只是新建了一个可移动的指针 那么git是如何知道我们处在哪个分支上的呢?
git通过HEAD的特殊指针标识你所处分支
# 分支切换
git checkout testing
快进合并
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并时我们看到了快进(Fast-forward),说明当前master
分支所指向的提交是当前提交(有关 hotfix 的提交)的直接上游,所以 Git 只是简单的将指针向前移动
三方合并
我们更多遇到的是要合并的两个分支所做的修改已经产生不同的推进
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的工作祖先(C2),做一个简单的三方合并
合并后,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交
Git 会自行决定选取哪一个提交作为最优的共同祖先,并以此作为合并的基础
推荐使用vscode或其他IDE操作...
整合不同的分支除了常用的merge
以外,还有rebase
操作
我们也可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 在 Git 中,这种操作就叫做rebase
(变基)。 你可以使用rebase
命令将提交到某一分支上的所有修改都移至另一分支上
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master)的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用
$ git checkout master
$ git merge experiment
rebase
命令可以让并行的工作历史记录变成串行一样,从而保证整个提交历史的整洁。这也是大多数开源项目贡献代码的方式。
当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态,而这时你想要切换到另一个分支做一点别的事情。
问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。
针对这个问题的答案是 git stash
命令
该命令会处理工作目录的脏的状态 - 即,修改的跟踪文件与暂存改动 - 然后将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动
# 查看储藏列表
git stash list
# 导出储藏记录
git stash apply <index>
# 清除储藏记录
git stash drop <index>
# 快速导出储藏并丢弃
git stash pop
建议大家进行ssh配置,整体效率更高。 具体操作流程参考gitlab的ssh配置指引
可以在.ssh目录下建立config文件来进行多账户配置
Host code.zikuinfo.com
User chengyupeng
HostName code.zikuinfo.com
IdentityFile ~/.ssh/id_rsa
Host github.com
User Username
HostName github.com
IdentityFile ~/.ssh/id_rsa_work
# 配置完成进行ssh连接确认
ssh -T git@<HostName>.com