作者:echozh
链接:https://juejin.im/post/5d5b4c6951882569eb570958
前置条件:
在正式开始之前,我们需要先确定几个概念。下面所提到的 master 分支默认为代码提交的主分支。
本地分支和远程分支
本地分支是指我们在日常开发中自己通过 git checkout branch xxx
建立的分支,远程分支是我们经过 git push -u origin xxxx
推到 git 服务器的分支,在我们推送之后,git 会帮我们在本地建立一个以 orgin/
开头的分支,这个我们也叫远程分支。
我们日常操作的就是本地分支 xxx 和远程分支 origin/xxx
,origin/xxx
就是远程的 git 服务器在我们本地建立的一个分支的对照版本(我觉得这样说应该比较容易理解),我们日常的 git fetch --all
就是将本地的 origin/xxx 与 git 服务器的 origin/xxx 分支进行同步。
commit id
我们每次提交代码都会根据本次提交的内容生成一个几乎唯一的 id ,这个 id 重复的概率几乎为 0,我们可以这样理解,我们每次的提交都会生成一个唯一索引的记录,不管是本地的 git,还是远程的 git ,我们都将她理解为一个数据库,只要我们进行了 commit 操作,那么可以几乎确定,我们的代码是不会丢失的,我们都可以通过 commit id 找到那条提交记录的内容。
本篇文章不会讲解,分支与分支之间的版本比较等内容,作者比较菜,怕掌握不好度翻车。
使用指南
创建分支
创建分支我们可以使用 git checkout branch xxx
来创建一个新分支,这个很容易理解,但是如果我们现在在分支 branch-1,但是我们想新建一个基于远程 master 最新版本的分支,我们该怎么办呢,不能说现在我回到 master,然后 git pull
拉取最新的 master 分支代码,然后创建分支,很繁琐对不对。
这里我们就可以进行里一个操作了:git fetch --all
记得我们上面提到的吧,同步远程分支代码, --all
可以改成 origin/master
,然后进行 git checkout branch xxx origin/master
后面的 origin/master
代表我们是基于远程分支 origin/master 进行创建的。
追加提交记录
比如我现在已经在本地 commit 一次了,但是发现还有东西忘改了,如果我在 commit 一次就会生成两条记录,这样从提交记录上看可能不太好看,然后我们就可以使用 git commit --amend
对上一次的提交记录进行追加。
这个操作的前提是上一次提交必需没有推送到远程分支,否则,你会发现操作之后在进行 git push
会提示你版本不一致不允许提交,当然如果你可以保证提交没有错误,且这一个分支只有你自己一个人玩,那你就可以使用 git push -f
进行强制提交了,这个操作很危险,谨慎使用。
merge 还是 rebase
我比较喜欢 rebase 操作,所以在这里就只会讲解 rebase 操作了。rebase 的使用场景。
使用场景 1:
比如现在你在 branch-a 分支工作,但是这个任务有点困难,你已经在这个分支工作很长时间了,很长时间都没有同步 master 分支的代码了,然后同组的小伙伴合并了一个新功能这个功能你需要使用,这个时候你就可以在当前分支使用 git rebase origin/master
了,这个操作会将你在这个分支的提交附加于最新的 master 分支版本之后,很明显这个操作之后你当前本地的 branch-a 和远程的 origin/branch-a
已经不一样了,所以有一个缺点就是你只能选择 git push -f
进行提交。
使用场景 2:
你同组的小伙伴修改了你在 branch-a 分支也修改过的代码,并且你的小伙伴已经提交了,这个时候,你的 branch-a 分支就会和 origin/master
分支有冲突,嗯,这个时候你也可以使用 git rebase origin/master
这个操作来解决冲突,并同步最新的 master 的代码。
使用场景 3:
你和小伙伴共同在 branch-a 分支提交代码,结果小伙伴比你先提交了,这个时候你再提交会发现版本不一致无法提交,这个时候我们就推荐使用 git pull --rebase
,其实 git pull
命令后面是有一个默认参数的那就是 --merge,会给我们刚接触 git 的同学造成很多麻烦。所以在这 git pull --rebase
是一个不错的选择。
rebase 的另外一个骚操作:合并 commit
git rebase -i HEAD~X x
代表从当前的提交记录往回回溯的提交记录的个数,执行这个操作之后我们就可以看到一个这样的交互界面:
上面我的 x 是 5,所以在这会有 5 个记录,接下来我们需要以一个记录为目标,将其他的记录全都合并到目标记录:
我们将其他的 pick 改为 s,s 是指 squash,下面截图的下面会有相应的解释,然后我们只需要保存退出即可,接下来会跳出一个 commit message
填写的界面:
这个界面是让我为新的提交记录填写新的 commit message
,这个可自行发挥,然后还是保存退出即可。然后我们使用 git log
就可以看到一个新的提交记录:
git cherry-pick
我们可能会有这样一个使用场景,在分支 branch-a 需要分支 branch-b 的某次提交,这个时候我们就可以先找到 branch-b 的那次提交记录的 id,然后在 branch-a 分支进行 git cherry-pick b-commit-id
将 branch-b 分支的提交记录拿过来了
那如果我们只需要 branch-b 分支的某个文件呢该怎么办呢,莫慌再交你一个操作,git checkout xxx file
这个操作可以将其他分支的文件拉取到当前分支,注意这个操作是覆盖式的,也就是如果你这个分支的这个文件已将存在,那么这个操作将会覆盖你当前分支的这个文件。可以发挥一下 xxx 也可以是远程分支。
git checkout branch -- file
那么这个操作又是干嘛的呢,这个操作可以将你的某个文件还原到某个分支的版本。如果某次你手误提交了错误的文件,但是改动又忘了,那么这个命令或许可以帮到你。
git prune
根据官方的解释,直白一点的翻译就是删除 git 数据库中不可访问的对象,那我的理解是这样的,git prune
删除的是你本地 .git 下的 object 目录下,没有被使用到的 hash 值,我理解的是它会删除 origin/xx 开头的没有用到的分支,这个分支在你的远程的 git 服务器中已经删除但是本地任然存在 origin/xxx 的映射,这个时候你就可以使用 git prune
来删除本地的 origin/xxx 的映射。
但是官方推荐使用的是 git gc,而想删除本地的 xxx 分支,就只能只用 git branch -D XXX
,在这附上一条我们部门自己写的一个清除本地无用分支的 shell git fetch --all --prune && git branch -vv | grep gone | awk '{ print $1 }' | grep -v pit | xargs git branch -D
。
git stash
git stash
可以帮助我们来暂存一些更改,我推荐的是如果只是少部分的更改,使用 stash 是可以的,多了的话,推荐新建分支来保存更改,以免自己忘记了哪个 stash。那我们该如何取出这些更改呢,最常用的就是 git stash pop
它会将你最新一次的 stash 从一个缓存数组里面推出来,这样的话如果我们操作不当很可能就丢失了这些更改。
我推荐的是使用 git stash apply
,这个会将你最新一次的 stash 从缓存数组里面 copy 一个副本返还给你,缺点就是,你本地的 stash 数组会越来越大,当然,你可以定时清空一下。还有一个场景,如果我想取出指定的 stash 该怎么办呢,在这我们可以使用 git stash list 来查看一下自己本地的 stash 记录的形式:
我圈出来的就是每次 stash 的类似于 id 的一个东西,后面会显示是在什么分支 stash 的,所以现在我们就可以使用 git stash pop/apply stashid
来取出指定的 stash。
后记
目前觉得这些在日常工作中使用的比较多,还有一个 patch 没说,因为用得比较少,如果再想到其他的内容我会在这篇文章上进行修改。如果本文有错误的地方还请大家可以指正,谢谢。
网友评论