

作者:echozh
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 分支进行同步。
我们每次提交代码都会根据本次提交的内容生成一个几乎唯一的 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 进行强制提交了,这个操作很危险,谨慎使用。
我比较喜欢 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 是一个不错的选择。
git rebase -i HEAD~X x 代表从当前的提交记录往回回溯的提交记录的个数,执行这个操作之后我们就可以看到一个这样的交互界面:

上面我的 x 是 5,所以在这会有 5 个记录,接下来我们需要以一个记录为目标,将其他的记录全都合并到目标记录:

我们将其他的 pick 改为 s,s 是指 squash,下面截图的下面会有相应的解释,然后我们只需要保存退出即可,接下来会跳出一个 commit message 填写的界面:

这个界面是让我为新的提交记录填写新的 commit message,这个可自行发挥,然后还是保存退出即可。然后我们使用 git log 就可以看到一个新的提交记录:

我们可能会有这样一个使用场景,在分支 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 数据库中不可访问的对象,那我的理解是这样的,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 可以帮助我们来暂存一些更改,我推荐的是如果只是少部分的更改,使用 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 没说,因为用得比较少,如果再想到其他的内容我会在这篇文章上进行修改。如果本文有错误的地方还请大家可以指正,谢谢。
打卡送书活动
活动介绍:自律改变自我!打卡送书活动启动!
活动奖品:技术书籍 × 7
赞助商:清华大学出版社
本书是机器学习和深度学习领域的入门与提高教材,紧密结合工程实践与应用,系统、深入地讲述机器学习与深度学习的主流方法与理论。本书理论推导与证明详细、深入,结构清晰,详细地讲述主要算法的原理与细节,让读者不仅知其然,还知其所以然,真正理解算法、学会使用算法。

本公众号全部博文已整理成一个目录,请在公众号里回复「m」获取!
推荐阅读:
5T技术资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,单片机,树莓派,等等。在公众号内回复「1024」,即可免费获取!!
