Git 版本控制

2020-11-07 约 2978 字 阅读时长6 分钟

Git

Git是一个分布式版本控制系统

中央服务器存在,仅仅是为了方便交换修改

基本使用

版本库:是一个目录,目录中所有文件都被Git管理起来,每个文件的删除、修改 Git都能跟踪

基本命令

bash
1Git init		#将目录初始化为Git仓库,会多一个.Git的隐藏目录
2
3Git add readme.txt		#将 readme 文件添加到仓库暂存区,可以添加多次
4
5Git commit -m "message"		#将暂存区的所有内容一次性提交到仓库

版本管理

在Git中 HEAD 用于表示当前版本

Git跟踪并管理的是修改,而非文件 第一次修改 -> Git add -> 第二次修改 -> Git commit,只会提交第一次修改

命令

bash
 1Git status		#查看仓库当前状态
 2
 3Git diff readme.txt		#查看 readme 修改的具体内容,add之前使用
 4Git diff HEAD readme.txt	#查看当前版本库 readme 修改内容
 5
 6Git log		#查看历史记录,--pretty=oneline 参数显示一行
 7
 8Git reset --hard HEAD^		#回退到上个版本,将HEAD指向上个版本
 9
10Git reset --hard 1094a		#回退到指定版本号;版本号缩写,可以通过 Git log 查看
11
12Git reflog		#查看操作的所有命令
13
14Git restore --staged readme.txt		#丢弃暂存区 readme ,回退到add之前状态
15Git restore readme.txt  #丢弃未提交到暂存区 readme,回退到上次 commit 状态
16
17Git rm	readme.txt	#删除文件
18Git checkout -- readme.txt		#版本库里的版本替换工作区的版本,恢复删除文件

远程仓库

Git支持多种协议,包括https,但ssh协议速度最快

命令

bash
 1Git remote -v		#查看远程仓库信息
 2
 3Git remote rm origin		#解除本地与远程仓库的关联
 4
 5Git remote add origin Git@server-name:path/repo-name.Git		#关联远程仓库,远程仓库名 orign 是习惯
 6
 7Git pull orign		#pull远程仓库内容
 8
 9Git push -u origin master		#第一次推送master分支的所有内容
10
11Git push origin master		#推送本地分支master最新修改
12Git push origin dev			#推送本地分支dev最新修改
13
14Git clone		#从远程仓库克隆

分支管理

分支:创建一个属于自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上

  1. 一条master主分支

    Git-br-initial

  2. 创建dev分支

    Git-br-create

  3. dev分支提交

    Git-br-dev-fd

  4. 合并dev分支

    Git-br-ff-merge

  5. 删除dev分支

    Git-br-rm

命令

bash
 1Git checkout -b dev		#-b参数,创建并切换到dev分支,相当于下面两条命令
 2Git branch dev		#创建dev分支
 3Git checkout dev		#切换到dev分支
 4
 5Git switch -c dev		#创建并切换到dev分支,命令switch更合理
 6Git switch dev		#切换到已存在dev分支
 7
 8Git branch		#列出所有分支
 9
10Git merge dev		#合并dev分支到当前分支
11
12Git branch -d dev		#删除dev分支
13Git branch -D dev    	#强行删除,当dev分支未合并时,强行删除dev分支

相对引用

bash
 1#将main分支指向哈希值为C6的提交记录
 2Git branch -f main c6
 3
 4#将HEAD指向HEAD的上一级
 5#HEAD^ HEAD~ 表示上一级, HEAD~2 HEAD^^表示上两级
 6Git checkout HEAD~
 7
 8#将bugFix分支指向HEAD的上一级
 9Git branch -f bugFix HEAD~
10
11#将HEAD分支指向哈希值为C4的提交记录
12Git checkout C4

撤销变更

bash
 1#撤销更改主要是 reset撤销本地,revert撤销远程
 2
 3#直接撤销本地修改,将HEAD指向指定分支,修改记录还在,未添加暂存区
 4Git reset HEAD~
 5
 6#切换pushed分支
 7Git checkout pushed
 8
 9#撤销当前HEAD指向的提交记录,远程仓库修改,需push到远程仓库
10#此时Git新建一次提交记录节点,该节点状态和HEAD上级分支节点状态一致
11Git revert HEAD

整理提交记录

‘我想要把这个提交放到这里, 那个提交放到刚才那个提交的后面’

Git cherry-pick

image-20220210160544217

bash
1#Git cherry-pick <提交号>...
2#将哈希值为c3,c4,c7的记录复制一份到HEAD所指向的分支上
3Git cherry-pick c3 c4 c7

交互式的 rebase

当你知道你所需要的提交记录(并且还知道这些提交记录的哈希值)时, 用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。但是如果你不清楚你想要的提交记录的哈希值呢? 可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录, 这就是最好的方法了

交互式 rebase 指的是使用带参数 --interactive 的 rebase 命令, 简写为 -i

rebase UI界面能做3件事:

  • 调整提交记录的顺序(通过鼠标拖放来完成)
  • 删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)
  • 合并提交。 遗憾的是由于某种逻辑的原因,我们的课程不支持此功能,因此我不会详细介绍这个操作。简而言之,它允许你把多个提交记录合并成一个
bash
1#取HEAD指向分支上四个提交节点打开交互式rebase
2Git rebase -i HEAD~4

杂项

image-20220210161910324

bash
1#交互式rebase
2Git rebase -i HEAD~3
3
4#将main分支指向哈希值为C4'的提交记录
5Git branch -f main C4'

合并冲突

  1. 两个分支修改了一个文件时

    Git-br-feature1

  2. 手动解决冲突,然后提交

    Git-br-conflict-merged

  3. 删除分支Git branch -d dev

Git status可以查看冲突文件

Git log可以看到分支合并情况

Git log --graph查看分支合并图

Git log --graph --pretty=oneline --abbrev-commit可以查看分支合并情况简图

--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并

bug分支

命令

bash
 1Git stash		#存储当前分支工作现场(主要存储未提交)
 2
 3#切换到有bug的分支,然后创建分支,假定为master
 4Git checkout master
 5Git checkout -b issue-101
 6#修复完成后提交,并删除issue-101分支
 7Git switch master
 8Git merge --no-ff -m "merged bug fix 101" issue-101	
 9
10#切换到工作分支
11Git switch dev
12
13Git stash list		#查看stash存储内容
14
15Git stash apply		#恢复工作现场,不删除stash存储内容
16Git stash drop		#删除stash存储内容
17
18Git stash pop		#恢复工作现场,并删除stash存储内容
19
20#将master分支上修复的bug,重放到当前分支
21Git cherry-pick 4c805e2		#复制一个特定的提交到当前分支

小结

  • 修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
  • 当手头工作没有完成时,先把工作现场Git stash一下,然后去修复bug,修复后,再Git stash pop,回到工作现场;
  • 在master分支上修复的bug,想要合并到当前dev分支,可以用Git cherry-pick <commit>命令,把bug提交的修改“复制”到当前分支,避免重复劳动

多人协作

多人协作工作模式

  1. 首先,可以试图用Git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用Git pull试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用Git push origin <branch-name>推送就能成功!

如果Git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令Git branch --set-upstream-to <branch-name> origin/<branch-name>

总结

  • 查看远程库信息,使用Git remote -v
  • 本地新建的分支如果不推送到远程,对其他人就是不可见的;
  • 从本地推送分支,使用Git push origin branch-name,如果推送失败,先用Git pull抓取远程的新提交;
  • 在本地创建和远程分支对应的分支,使用Git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
  • 建立本地分支和远程分支的关联,使用Git branch --set-upstream branch-name origin/branch-name
  • 从远程抓取分支,使用Git pull,如果有冲突,要先处理冲突

git的其他命令

  1. Git 暂时忽略文件修改

    bash
    1# 暂时停止追踪文件改动
    2git update-index --assume-unchanged <文件路径>
    3
    4# 重新开始追踪该文件的变化
    5git update-index --no-assume-unchanged <文件路径>
  2. 仓库各部分的详细大小分布

    bash
     1git count-objects -vH
     2
     3: '
     4输出信息:
     5count: 0           # 未打包的松散对象数量
     6size: 0.00 KiB     # 松散对象占用的空间
     7in-pack: 123       # 打包在 packfile 中的对象数量
     8packs: 1           # packfile 的数量
     9size-pack: 4.00 MiB # 打包对象占用的空间
    10prune-packable: 0  # 可被移除的冗余对象数量
    11garbage: 0         # 无关文件数量
    12size-garbage: 0 B  # 无关文件占用的空间
    13'
使用滚轮缩放
按住拖动