文章目录
一、基本概念
我们先来理解下 Git 工作区、暂存区和版本库概念:
1、版本库
工作区有一个隐藏目录 .git,这个就是 Git 的版本库。
2、HEAD
当前分支版本的顶端。
3、暂存区 (Index)
常叫做 staging area 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
4、工作区(Working Copy)
就是你在电脑里能看到的文件目录。
这里可以理解为 git 本地的版本库中,有一个文件结构树对应与远程分支代码结构,然后本地还有一个文件暂存区以及工作区。
操作节点 | 三者异同状态 |
---|---|
check out 出来一个新分支 | 三者是相同的 |
修改过文件、新增或删除了文件 | HEAD、Index相同; 工作区发生了变化 |
git add 添加到暂存区 | HEAD不变;Index 与 工作区相同 |
git commit 提交到本地仓库 | 三者又相同了 |
二、Git 常用命令
1、git add 将该文件添加到暂存区
- 添加一个或多个文件到暂存区:
git add [file1] [file2] ...
- 添加指定目录到暂存区,包括子目录:
git add [dir]
- 添加当前目录下的所有文件到暂存区:
git add .
2、git commit 将暂存区内容添加到本地仓库中
- 提交暂存区到本地仓库中:
git commit -m [message]
其中 [message] 一般是一些备注信息,用双引号包裹。 - 提交暂存区的指定文件到仓库区:
git commit [file1] [file2] ... -m [message]
- -a 参数设置修改文件后不需要执行 git add 命令,直接来提交:
git commit -a -m [message]
或git commit -am [message]
其实,git commit -a 相当于运行 git add 把所有当前目录下的文件加入暂存区域再运行 git commit。
3、git pull 从远程获取代码并合并到本地
- 基本用法:
git pull <远程主机名> <远程分支名>:<本地分支名>
例如执行下面语句:
git pull origin master:master
,表示将远程主机origin的master分支拉取过来,与本地的master分支合并。 - 如果远程分支(master)要与当前分支合并,则冒号后面的部分可以省略:
git pull origin master
git pull
是git fetch
后跟git merge FETCH_HEAD
的缩写。
更准确地说,git pull
使用给定的参数运行git fetch
,并调用git merge
将检索到的分支头合并到当前分支中。
- 推荐用法:
git pull --rebase
这里与git pull
的区别在于:
git pull 相当于 git fetch + git merge
git pull --rebase 相当于 git fetch + git rebase
介绍一下 git fetch
会从远程获取最新版本到本地,不会自动合并分支
例如:
两个人同时在一个分支开发时,当前该分支提交记录节点为 01,然后两个人都从 01 节点check out 出来自己的本地分支,然后开始写自己的代码。
这时候,你写完你的代码了,打算提交自己的代码时,发现另一个哥们比你写的快,他已经把他的代码提交到了远程分支上。这时候你本地假设为 01 — 03,而你本地分支对应的远程分支已经被那哥们更新为 01 — 02 了。那么此时当你把自己的代码执行完 git add 和 git commit 之后:
一、你采用了 git pull
这时候分支的节点会变成 01 — 03 — merge 。也就是说,你的这个操作会把那哥们之前的提交记录更新为一次 merge 的 commit 提交到分支上。如果这个哥们提交了多次代码,那么这个 merge commit 就包含了多次的提交记录。
二、你采用了 git pull --rebase
这种情况,因为 git fetch 执行完之后,没有执行 git merge 而是执行的 git rebase 。
介绍一下 git rebase
git rabse 翻译过来就是“变基”的意思,或者理解为“衍合”的意思。
使用了 git rebase 会重新定义当前分支的版本库状态的起点。
之前我们的本地分支从远程分支01拉取出来的,但是在提交代码之前远程分支的最新提交节点已经变成了02,所以如果用git rebase 会重新来调整我们本地的分支check out 的根基节点。相当于我们成了从 02 拉取出来分支,然后做了修改。再提交回去后就变成来 01 — 02 — 03。
4、git push 把本地的分支推送到远程分支进行合并
- 命令格式如下:
git push <远程主机名> <本地分支名>:<远程分支名>
- 如果本地分支名与远程分支名相同,则可以省略冒号:
git push <远程主机名> <本地分支名>
以下命令将本地的 master 分支推送到 origin 主机的 master 分支。
git push origin master
相等于:
git push origin master:master
其他用法:
- 如果本地版本与远程版本有差异,但又要强制推送可以使用 --force 参数:
git push --force origin master
(这里可以配合 git reset 先重置 HEAD 然后再 push 到远程分支,达到撤销掉已经 push 到远程分支的提交记录及代码) - 删除主机但分支可以使用 --delete 参数,以下命令表示删除 origin 主机的 master 分支:
git push --delete origin master
常用的一系列操作命令:
git status // 查看文件、文件夹在工作区,暂存区的状态
git add . // 添加到暂存区
git commit -m '提交说明' // 提交到本地仓库
git pull --rebase // 从远程分支做变基更新
git push origin [本地分支]:[远程分支] //提交到服务器
三、其他操作
1、合并本地的多次提交记录
(1)git log 查看所有的git 记录
commit 7a118515b655f36ecb3b0d18feff9ca1ddf67b23 (HEAD -> develop1)
Author: yan
Date: Tue Mar 31 18:19:43 2020 +0800
add 7
commit a704085efa4488e33b704670851d6fa4ddc84b3a
Author: yan
Date: Tue Mar 31 18:19:26 2020 +0800
add 6
commit 3ac0a1f2f88467e7e76aba21ebd7d7d26502a75e
Author: yan
Date: Tue Mar 31 18:18:10 2020 +0800
add 5
commit d5d40c7d0d983c4e5ca50e8222f31114bcaa1fe9 (origin/master, origin/develop1, master)
Author: yan
Date: Tue Mar 31 17:30:27 2020 +0800
添加3 和 4
我们现在准备项合并 add 7 + add 6 + add 5
(2)git rebase -i commitId
这里的commitId
指的是想要合并的最后一条的下一条记录也就是d5d40c7d0d983c4e5ca50e8222f31114bcaa1fe9<添加3 和 4>
按下 q 退出 git log 查询
前提条件,本地没有可以提交的东西。不然会报错
git rebase -i d5d40c7d0d983c4e5ca50e8222f31114bcaa1fe9
(3)修改关键字
进入vi模式后,在键盘上敲 i 键进入 insert 模式。这时候先看看这里面的东西是什么含义,
pick 的意思是要会执行这个 commit
squash 的意思是这个 commit 会被合并到前一个commit
我们这边需要将【add 7】和【add 6】合并到【add 5】中,那就需要修改成如下的:
修改完成后,按esc键,冒号,输入wq进行保存。之后会继续跳转到commit message 的编辑界面,可以在这个地方修改commit的message,不修改,默认是这几次的commit message的集合。
(4)验证
git log
可以看到,原本我们分为来3次的 commit 【add 5、add 6、add 7】被合并为了一次 commit 记录。
2、git rebase 有冲突时处理
git rebase --abort
放弃合并,回到 rebase 操作之前的状态,之前的提交不会丢失。git rebase --skip
会将引起冲突的 commit 丢弃掉。【慎用】git rebase --continue
合并当前的冲突。
必须是有合并冲突产生时命令才可以执行。
3、git reset 命令的使用
git reset
用于回退版本,可以指定退回某一次提交的版本。
首先,我们回顾一下 HEAD、Index、工作区三者之间的关系变化:
操作节点 | 三者异同状态 |
---|---|
check out 出来一个新分支 | 三者是相同的 |
修改过文件、新增或删除了文件 | HEAD、Index相同; 工作区发生了变化 |
git add 添加到暂存区 | HEAD不变;Index 与 工作区相同 |
git commit 提交到本地仓库 | 三者又相同了 |
那么,git reset 不同的操作分别是如何回退版本的呢?
git reset --soft [HEAD]
更改 HEAD,用于恢复 git commit 操作。git reset --mixed [HEAD]
【默认项】
重置 HEAD 到另外一个 commit ,并且重置 Index 以便与 HEAD 相匹配。用于恢复 git commit 以及 git add 操作。git reset --hard [HEAD]
强制恢复 HEAD、Index、工作区三者到同一次 commit。撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交。
【谨慎使用 –hard 参数,它会删除回退点之前的所有信息】
git reset --hard HEAD
HEAD 说明:
- HEAD 表示当前版本
- HEAD^ 上一个版本
- HEAD^^ 上上一个版本
- HEAD^^^ 上上上一个版本
- 以此类推…
可以使用 ~数字表示
- HEAD~0 表示当前版本
- HEAD~1 上一个版本
- HEAD^2 上上一个版本
- HEAD^3 上上上一个版本
- 以此类推…
4、如何撤回已经 push 到远程的代码
如果不小心把错误的代码 push 到了远程分支,或者 push 完代码到远程分支后突然发现有问题,想要撤回而不是重新修改后再 push 一次该怎么办呢?
只需要三步操作:
git log
查看一下提交历史记录,找到要撤回 commit 前一次的 commit id。git reset --soft [commit id]
回滚本地代码仓库的版本到要撤回提交的上一个版本。git push origin [本地分支名]:[远程分支名] --force
强制将本地仓库的代码推送到远程仓库即可。
关于撤回已经 push 到远程的代码的详细介绍,可以查看该文章:>> 传送门 <<