我之前有一份私人git笔记老长老长了, 今天得空, 把它浓缩成5分钟版本.
感觉纯基础性的东西整理成博客差也差不多了, 还有很多凌乱的工作笔记慢慢在一点一点整理放上来吧,
估计下面几篇博客就开始游戏服务器的开发心得之类的了.本篇博客因为要5分钟撸完git, 所以语言尽量精简, 只说新人必须知道的, 如果要git进阶的, 后面再另写博客说明, 不该说的废话就不说了
安装
sudo apt-get install git
查看状态
- 比如查看当前分支的状态 : git status, 这条命令也会给很多其他的git命令提示的喔
- 查看当前在哪个分支 : git branch
b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git branch
master
new_test_branch
* old_demo
plugin
标记为*的那个就是当前分支, 也就是old_demo分支
克隆
比如从我的一个远端github项目克隆一份到本地 : git clone git@github.com:nosix1992/Flock-AI-Fish-Unreal-VR.git
这个地址是这样得来的, 如图 :
分支
- 比如创建一个新的分支test_branch : git branch test_branch
- 比如切换到分支test_branch : git checkout test_branch
比如把test_branch合并到主分支master上来 : 先切换到master上来git checkout master 然后
- git merge test_branch
- git rebase test_branch
rebase 跟 merge 的区别你们可以理解成有两个书架,你需要把两个书架的书整理到一起去,第一种做法是 merge ,比较粗鲁暴力,就直接腾出一块地方把另一个书架的书全部放进去,虽然暴力,但是这种做法你可以知道哪些书是来自另一个书架的;第二种做法就是 rebase ,他会把两个书架的书先进行比较,按照购书的时间来给他重新排序,然后重新放置好,这样做的好处就是合并之后的书架看起来很有逻辑,但是你很难清晰的知道哪些书来自哪个书架的。各有好处的,不同的团队根据不同的需要以及不同的习惯来选择就好。
比如删除分支test_branch :
- git branch -d test_branch
- git branch -D test_branch
有些时候可能会删除失败,比如如果a分支的代码还没有合并到master,你执行 git branch -d a 是删除不了的,它会智能的提示你a分支还有未合并的代码,但是如果你非要删除,那就执行 git branch -D a 就可以强制删除a分支。
提交
- 比如将修改之后的文件test_file加入到暂存区里 : git add test_file
- 撤销刚刚的git add(也就是说把test_file从暂存区中移出) : git reset HEAD test_file
- 比如将暂存区里的提交并加入提交信息”update test_file” : git commit -m “update test_file”
- 把git commit撤销 :
- 只是把commit撤销并且把文件从暂存区中移出, 但保留已有的文件更改 : 通用命令为 git reset commit_id, 这个commit_id用git log命令来查看, 比如要恢复到刚刚提交的上一次提交的版本, 就用git reset HEAD^(这句命令的意思是说: 恢复到commit id 为HEAD^的版本, HEAD是指向最新的提交,上一次提交是HEAD^,上上次是HEAD^^,也可以写成HEAD~2 ,依次类推. )
- 把commit撤销且不保留已有的文件更改 : git reset –hard commit_id
- 把git commit撤销 :
比如只是撤销某个文件test_file的修改 : git checkout –test_file
将代码推到远端 : 这之前的所有这些add, commit都是本地仓库的操作, 比如我们把本地的master分支推到github的那个项目的master分支 : git push origin master
贮藏stash
设想一个场景,假设我们正在一个新的分支做新的功能,这个时候突然有一个紧急的bug需要修复,而且修复完之后需要立即发布。当然你说我先把刚写的一点代码进行提交不就行了么?这样理论上当然是ok的,但是这会产品垃圾commit,原则上我们每次的commit都要有实际的意义,你的代码只是刚写了一半,还没有什么实际的意义是不建议就这样commit的,那么有没有一种比较好的办法,可以让我暂时切到别的分支,修复完bug再切回来,而且代码也能保留的呢?
试试git stash吧
- git stash : 把当前的文件改动贮藏起来
- git stash list: 查看当前有哪些贮藏记录
- git stash pop stash_list_id: 会帮你把代码还原,还自动帮你把这条 stash 记录删除
b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git checkout old_demo error: Your local changes to the following files would be overwritten by checkout: README.md Please, commit your changes or stash them before you can switch branches. Aborting b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git stash Saved working directory and index state WIP on new_test_branch: b3ad5d2 modify md HEAD is now at b3ad5d2 modify md b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git checkout old_demo Switched to branch 'old_demo' Your branch is up-to-date with 'origin/old_demo'. b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git checkout new_test_branch Switched to branch 'new_test_branch' b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git stash list stash@{0}: WIP on new_test_branch: b3ad5d2 modify md b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git stash pop stash@{0} On branch new_test_branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a") Dropped stash@{0} (88cd440c10c80bb6eaef9f4d86ab4a0be3d6dc00)
对比diff
- 比如查看当前还未git add的文件的不同 : git diff
- 比如查看当前已经add 没有commit 的改动 : git diff –cached
- 比如查看当前所有改动和HEAD的区别(当前还未git add的文件的改动和当前当前已经add 但没有commit 的改动), 也就是上面两条命令的合并 : git diff HEAD
- 比如查看 commit_id为a和commit_id为b的temp文件夹的差异 : git diff a b temp
处理冲突
假设这样一个场景,A和B两位同学各自开了两个分支来开发不同的功能,大部分情况下都会尽量互不干扰的,但是有一个需求A需要改动一个基础库中的一个类的方法,不巧B这个时候由于业务需要也改动了基础库的这个方法,因为这种情况比较特殊,A和B都认为不会对地方造成影响,等两人各自把功能做完了,需要合并的到主分支 master 的时候,我们假设先合并A的分支,这个时候没问题的,之后再继续合并B的分支,这个时候想想也知道就有冲突了,因为A和B两个人同时更改了同一个地方,Git 本身他没法判断你们两个谁更改的对,但是这个时候他会智能的提示有 conflicts
就像下面这种情况 :
b@b-VirtualBox:~/git_test_link/Flock-AI-Fish-Unreal-VR$ git merge plugin Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
打开READ.md文件一看发现冲突的地方如下:
<<<<<<< HEAD mmmp ======= nani >>>>>>> plugin
冲突的地方由 ==== 分出了上下两个部分,上部分一个叫 HEAD 的字样代表是我当前所在分支的代码,下半部分是一个叫 plugin 分支的代码,可以看到 HEAD 是那里加了一行mmmp,而plugin分支则加了一句nani, 所以我们得跟团队的其他人商量一下看看要改成什么样,而且同时也要把那些 «< HEAD、==== 以及 »»»plugin 这些标记符号也一并删除,最后进行一次 commit 就ok了。
标签tag
主要介绍附注标签( annotated tag)
创建附注标签
git tag -a v0.1.2 -m “0.1.2版本”
创建轻量标签不需要传递参数,直接指定标签名称即可。
创建附注标签时,参数a即annotated的缩写,指定标签类型,后附标签名。参数m指定标签说明,说明信息会保存在标签对象中。切换到标签
与切换分支命令相同,用git checkout [tagname]
查看标签信息
用git show命令可以查看标签的版本信息:
git show v0.1.2删除标签
误打或需要修改标签时,需要先将标签删除,再打新标签。
git tag -d v0.1.2 # 删除标签参数d即delete的缩写,意为删除其后指定的标签。
给指定的commit打标签
打标签不必要在head之上,也可在之前的版本上打,这需要你知道某个提交对象的校验和(通过git log获取)。
git tag -a v0.1.1 9fbc3d0标签发布
通常的git push不会将标签对象提交到git服务器,我们需要进行显式的操作:
git push origin v0.1.2 # 将v0.1.2标签提交到git服务器
git push origin –tags # 将本地所有标签一次性提交到git服务器- 比如将修改之后的文件test_file加入到暂存区里 : git add test_file