作为一名工程师,既然想要加入一个团队,并肩作战地协同开发项目,就必不可少要学会Git基本操作。
Git拥有哪些区
-
远程仓库(Remote):在远程用于存放代码的服务器,远程仓库的内容能够被分布其他地方的本地仓库修改。
-
本地仓库(Repository):在自己电脑上的仓库,平时我们用git commit 提交到暂存区,就会存入本地仓库。
-
暂存区(Index):执行
git add
后,工作区的文件就会被移入暂存区,表示哪些文件准备被提交,当完成某个功能后需要提交代码,可以通过git add
先提交到暂存区。 -
工作区(Workspace):工作区,开发过程中,平时打代码的地方,看到是当前最新的修改内容。
Git的基本使用场景
以下命令远程主机名默认为origin
,如果有其他远程主机,将origin
替换为其他即可。
git fetch
# 获取远程仓库特定分支的更新
git fetch orgin <分支名>
# 获取远程仓库所有分支的更新
git fetch --all
git pull
# 从远程仓库拉取代码,并合并到本地,相当于 git fetch && git merge
git pull orgin <远程分支名>:<本地分支名>
# 拉取后,使用rebase的模式进行合并
git pull --rebase orgin <远程分支名>:<本地分支名>
-
直接git pull 不加任何选项,等价于
git fetch + git merge FETCH_HEAD
,执行效果就是会拉取所有分支信息回来,但是只合并当前分支的更改。其他分支的变更没有执行合并。 -
使用git pull --rebase 可以减少冲突的提交点,比如我本地已经提交,但是远程其他同事也有新的代码提交记录,此时拉取远端其他同事的代码,如果是merge的形式,就会有一个merge的commit记录。如果用rebase,就不会产生该合并记录,是将我们的提交点挪到其他同事的提交点之后。
git branch
# 基于当前分支,新建一个本地分支,但不切换
git branch <分支名>
# 查看本地分支
git brach
# 查看远程分支
git brach -r
# 查看本地和远程分支
git brach -a
# 删除本地分支
git brach -D <分支名>
# 基于旧分支创建一个新分支
git brach <新分支名> <旧分支名>
# 基于某提交点创建一个新分支
git branch <new-branch-name> <commit-id>
# 重新命名分支
gir brach -m <old-brach-name> <new-brach-name>
git checkout
# 切换到某个分支上
git checkou <分支名>
# 基于当前分支,创建一个分支并切换到新分支上
git checkou -b <分支名>
git add
# 添把当前工作区修改的文件添加到暂存区,多个文件可以用空格隔开
git add 文件名
# 添加当前工作区修改的所有文件到暂存区
git add .
git commit
# 提交暂存区中的所有文件,并写下提交的概要信息
git commit -m "message"
# 相等于 git add . && git commit -m
git commit -am
# 对最近一次的提交的信息进行修改,此操作会修改commit的hash值
git commit --amend
git push
# 推送提交到远程仓库
git push
# 强行推送到远程仓库
git push -f
git tag
# 查看所有已打上的标签
git tag
# 新增一个标签打在当前提交点上,并写上标签信息
git tag -a <version> <commit-id>
# 删除指定标签
git tag -d <version>
Git的进阶使用场景
HEAD表示最新提交 ;HEAD^表示上一次; HEAD~n表示第n次(从0开始,表示最近一次)
正常协作
-
git pull
拉取远程仓库的最新代码 -
工作区修改代码,完成功能开发
-
git add .
添加修改的文件到暂存区 -
git commit -m 'message'
提交到本地仓库 -
git push
将本地仓库的修改推送到远程仓库
代码合并
git merge
自动创建一个新的合并提交点merge-commit
,且包含两个分支记录。如果合并的时候遇到冲突,仅需要修改解决冲突后,重新commit。
git checkout master
git merge dev
git merge 的几种模式
-
git merge --ff
(默认–ff,fast-farward)
- 结果:被merge的分支和当前分支在图形上并为一条线,被merge的提交点commit合并到当前分支,没有新的提交点merge
- 缺点:代码合并不冲突时,默认快速合并,主分支按时间顺序混入其他分支的零碎commit点。而且删除分支,会丢失分支信息。
-
git merge --no-ff
(不快速合并、推荐)
- 结果:被merge的分支和当前分支不在一条线上,被merge的提交点commit还在原来的分支上,并在当前分支产生一个新提交点merge
- 优点:代码合并产生冲突就会走这个模式,利于回滚整个大版本(主分支自己的commit点)
-
git merge --squash
(把多次分支commit历史压缩为一次)
- 结果:把多次分支commit历史压缩为一次
git rebase
- 不产生
merge commit
,变换起始点位置,“整理”成一条直线,且能使用命令合并多次commit。 - 如在develop上
git rebase master
就会拉取到master上的最新代码合并进来,也就是将分支的起始时间指向master上最新的commit上。自动保留的最新近的修改,不会遇到合并冲突。而且可交互操作(执行合并删除commit),可通过交互式变基来合并分支之前的commit历史git rebase -i HEAD~3
git checkout dev
git rebase master
取消合并
# 取消merge合并
git merge --abort
# 取消rebase合并
git rebase --abort
代码回退
代码回退的几种方式
git checkout
-
git reset
-
--hard
:硬重置,影响【工作区、暂存区、本地仓库】 -
--mixed
:默认,影响【暂存区、本地仓库】,被重置的修改内容还留在工作区 -
--soft
:软重置,影响 【本地仓库】,被重置的修改内容还留在工作区和暂存区
-
git revert
# 撤回工作区该文件的修改,多个文件用空格隔开
git checkout -- <file-name>
# 撤回工作区所有改动
git checkout .
# 放弃已git add到暂存区的指定文件的缓存(HEAD表示最新版本)
git reset HEAD <file-name>
# 放弃所有的缓存
git reset HEAD .
# 丢弃已commit的其他版本,hard参数表示同时重置工作区的修改
git reset --hard <commit-id>
# 回到上一个commit的版本,hard参数表示同时重置工作区的修改
git reset --hard HEAD^
# 撤销0ffaacc这次提交
git revert 0ffaacc
# 撤销最近一次提交
git revert HEAD
# 撤销最近2次提交,注意:数字从0开始
git revert HEAD~1
# 回退后要执行强制推送远程分支
git push -f
git reset和git revert的区别
-
reset是根据来移动HEAD指针,在该次提交点后面的提交记录会丢失。
-
revert会产生新的提交,来抵消选中的该次提交的修改内容,可以理解为“反做”,不会丢失中间的提交记录。
使用建议
- 公共分支回退使用git revert,避免丢掉其他同事的提交。
- 自己分支回退可使用git reset,也可以使用git revert,按需使用。
挑拣代码
git cherry-pick
- “挑拣”提交,单独抽取某个分支的一个提交点,将这个提交点的所有修改内容,搬运到你的当前分支。
- 如果我们只想将其他分支的某个提交点合并进来,不想用
git merge
将所有提交点合并进来,就需要使用这个git cherry-pick
。
git cherry-pick <commit-id>
暂存代码
git stash
-
当我们想要切换去其他分支修复bug,此时当前的功能代码还没修改完整,不想commit,就需要暂存当前修改的文件,然后切换到hotfix分支修复bug,修复完成再切换回来,将暂存的修改提取出来,继续功能开发。
-
还有另一种场景就是,同事在远程分支上推送了代码,此时拉下来有冲突,可以将我们自己的修改stash暂存起来,然后先拉最新的提交代码,再pop出来,这样可以避免一个冲突的提交点。
# 将本地改动的暂存起来
git stash
# 将未跟踪的文件暂存(另一种方式是先将新增的文件添加到暂存区,使其被git跟踪,就可以直接git stash)
git stash -u
# 添加本次暂存的备注,方便查找。
git stash save "message"
# 应用暂存的更改
git stash apply
# 删除暂存
git stash drop
# 应用暂存的更改,然后删除该暂存,等价于git stash apply + git stash drop
git stash pop
# 删除所有缓存
git stash clear
# 查看缓存列表
git stash list