本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
写在前面
之前都是使用AndroidStudio自带的图形化命令行,而身边的同事都是清一色的命令行...在如此的氛围之下,催生出了这篇记录学习的博客。
这篇博客并非如同文档那样一行行去讲解怎么用。而且记录我对Git的理解,以及导师给我讲的内容。
开始
初始化
我们如果想要对一个文件下的内容进行git管理,我们首先要进入这个目录下,然后执行:
git init
执行完毕后,我们可以看到这个目录下看到一个隐藏的.git文件,里边包含我们的git管理的信息。
比如在config里会记录我们的远程服务仓库的地址信息,以及依赖的子库情况...
暂存区的小操作
初始化过后我们就可以进行常用的git操作了。
我们改动某些文件后,git add xxx
。(如果我们修改内容过多可以使用git add .
)将xxx文件添加到暂存区。进入暂存区之后,我们的commit就可以追踪到文件的变化。
使用git commit -m "我要commit暂存区所有内容"
。此命令一出,暂存区所有内容将被我们提交。那么此时我们使用git status
会得到一个干净的工作区。
此时我们当前的内容便是最新的内容,如果后悔了,不想这次提交,怎么办?
版本回退
情况1:
如果我们完成了一些工作,进行了一次add操作(没有commit),并且接下来我们只是在工作区搞事情,没有涉及到add以及commit,那么如果我们想撤销现在工作区的操作,那么使用git checkout xxx
,此条命令一出,我们的工作区的文件便被撤销,注意所有的修改将被放弃再也找不到了。
此命令适用于场景:我们add的一部分操作,并且在这个add基础上进行了新内容的增加,如果我们感觉新加的内容没有意义,那么直接checkout就可以删除这些无意义的内到,回退到我们add时候的状态。
情况2:
如果我们把我们的先add了一次文件,并且没有新的内容增加(此时没有进行commit),而此时我们想要对之前add的内容进行撤销,那么此时我们就可以使用git reset HEAD xxx
,此命令一出我们的xxx便退出了暂存状态,被放回到了工作区。既然进入了工作区,那我们爱怎么checkout怎么checkout。
之前我对一些checkout/reset操作很迷,其实很简单:
当我们当前的修改没有被add时,可以使用checkout将当前的修改内容全部丢弃。
如果我们已经将修改内容add了,那么我们想要丢弃这些修改的内容,要使用reset,它的作用就是把add的修改在从暂存区拿出来。这样我们就回到了刚才那种情况,checkout即可。
情况3:
如果对我们的操作进行了commit操作,因为此时我们已经把工作内容提交了,所以我们此时的回退,只能回退到之前的提交版本。比如我们提交了一次git commit -m "v_1.0.0"
,此后我们有提交了一次git commit -m "v_1.0.1"
,以及git commit -m "v_1.0.2"
。那么此时我们存在了3次提交,如果我们使用git log
我们就可以看到这三次提交详细内容。如果我们想回退到v_1.0.0这个版本,那么我们需要在log中复制一下对应提交的SHA1,也就是那一串很长的字母与数字相错的字符串(不需要全复制,复制部分即可)。
回退的命令如下git reset --hard d1022e5
,此命令一出,我们的版本回到了v_1.0.0,如果此时我们再次使用git log
我们会发现v_1.0.1和v_1.0.2没了...如果我们后悔了想要再次回到v_1.0.2怎么办?我们使用git reflog
找到我们提交操作所有备份,找到对应v_1.0.2的SHA1的值,git reset --hard 对应的SHA1
即可。
当然这里也有一些不需要查找SHA1值的回退操作,比如:git reset --hard HEAD^
回退到上一个版本。以及git reset --hard HEAD~5
回退到上5个版本。
我们在使用
git log
时,会进入log界面,此时敲一下q便会退出log界面。
git log -2:表示只显示2个提交日志。
分支管理
命令branch:
git branch -vv
显示当前本地分支对应追踪的线上分支情况
git branch -u [remotename]/[branch]
改变当前分支的追踪对象
git branch
显示当前分支
git branch dev
创建dev分支
git branch -a
显示git所有分支情况,包括远程
命令checkout:
git checkout dev
切换到dev分支
git checkout -b dev
创建并切换到dev分支
git branch -d dev
删除当前分支,此条命令的前提:不能删除当前分支,删除的分支必须已经被合并
git branch -D dev
不问青红皂白直接删除
命令merge:
git merge dev
把dev分支的内容合并到自己这个分支上来,如果出现冲突(俩条分支都在同一行内容上进行了修改),需要合并者手动修改后在进行commit等一系列后续操作。
我们在当前分支进行的add,commit是不会影响到其他分支的操作。并且我们在没有进行commit的时候,是不允许就行切换分支操作。
但是如果我们情况实在紧急没办法等到这个分支任务完成commit后再切换到其他分支进行工作改怎么处理?
此时我们将使用git stash
此命令代表的含义是,先把我们当前分支工作区(也就是没有commit)的内容先存一下,我一会再回来用。那么既然当前的内容已经被存了,我们就可以切换分支去进行其他操作了。(注意stash完了之后,我们此时的内容是最新的commit一至,此时在没有恢复stash不要直接在此分支上进行操作)
在其他分支操作完毕后,紧接着便是回到我们自己并未完成工作的分支上去,checkout过来之后,我们此时我们有俩个命令可以选择:
-
git stash apply
:此命令默认回到最新的一次stash记录。这也就是说明了一个问题:stash存在记录,允许存在多次stash。也就是说只要我们能找到stash的记录,我们就可以切换到具体记录的stash工作内容。但是这里有一个前提。stash保留的工作内容要和当前的commit不一样。如果一样那就没有什么意义...当然我们也可以将当前的版本回退到之前的版本在进行stash。
这里我们如果我们的stash存在对跳记录那么我们的git stash apply
默认调出的是最新的stash,如果我们想要其他的,我们可以使用git stash list
查看想要的某一个stash记录,然后使用git stash apply stash@{x}
(x代表对应的版本)即可。 -
git stash pop
:弹出最新的stash并且把它从stash list之中删除。
命令rebase:
提到merge必须要要谈一谈rebase:
二者都是对分支内容进行合并,不同点文档说的很详细,简单来说:merge方式的合并会生成全新的节点,而rebase会把所有分支合并成一条线的结构,并且不会生成新的分支。
!个人被坑的地方:二者在处理合并冲突时不同:
merge:修完冲突正常add/commit即可
rebase:遇到冲突会被移动到一个临时分支上,处理好冲突之后,要使用git add . ;然后使用git rebase --continue操作,告诉git,这次冲突解决完成。(注意rebase是按节点的时间顺序进行合并,每次合并冲突,都会停下来,让我们修改完冲突。才会继续后边的节点合并。)
rebase在进行合并时会把当前分支的所有提交复制一份副本然后往想要合并的分支上去合并,每遇到一个冲突,都会停下来让你去解决,然后--continue继续进行合并,直到所有合并完成。
当然也可以使用rebase --abort,放弃合并,回退到没合并的状态。
远程仓库
正常情况下,我们都是进行了协同开发。因此我们势必需要一个共我们多人协同开发的服务器。这里比如我们使用了GitHub对我们的公共仓库进行托管。
那么我们只需要为我们当前这台机器生成一个ssh文件,并且把ssh的公钥设置到我们的GitHub上。我这样我们就可以我们自己的本地和我们自己的GitHub进行pull和push操作了。
那如果我想让我的其他基友也参与该怎么办?根据我们刚才的理论,只需要把基友的ssh公钥设置到我们的这个GitHub账号上来即可。
亦或者在GitHub之中手动添加协同用户。
正常我们本地与服务端建立联系,我们会通过clone的方式git clone xxx
(xxx是远程端的git的clone地址),在本地建立复制一个远程库,并建立关系。默认的名字是origin。我们可以在当前文件中的隐藏文件.git中的config之中看到具体的设置内容。
这是一种情况,另一种是通过add的方式,git remote add myremote xxx
,执行后如果我们进入config就会看到git为我们自动设置了一个名字为myremote的远程库的关系。
这样我们就可以正常的使用git pull/push myremote master
,进行拉和退的过程。这里的myremote是我们在config之后设置的名字,master是对应远程端的分支。
我们可能会遇到这种情况,一直在本地使用服务端的master分支,因为种种原因需要在本地切换到线上其他分支,那么我们可以这么做:
如果我想切换到这个线上分支:
remotes/origin/feature
那我的命令是:
git checkout -b [本地分支名] origin/feature
子库
命令submodule:
有时我们会遇到这种情况,clone的项目依赖了其他的项目。这个时候clone是不会把依赖的子库也clone下来的,我们需要手动git submodule init,然后又git submodule update即可。
如果嫌麻烦,可以在clone主项目的时候用这个命令:git clone --recursive 项目地址。
!如果远端子库节点被他人引成最新的,那么我们在pull下来的时候,需要update子库。此时不update的话,我们进行status操作,会提示子库有提交。
使用git branch -a可以查到当前的线上分支情况
从线上拉下一个分支,在本地创建自己设置的名字的分支上:git checkout -b [branch] [remotename]/[branch]
从线上拉下一个分支,在本地创建同名的分支上:git checkout --track [remotename]/[branch] (track前有俩个-)
删除线上分支:git push [remotename] --delete [branch]
命令补充:
git update-index --assume-unchanged /path/to/file //忽略跟踪
git update-index --no-assume-unchanged /path/to/file //恢复跟踪
git clone --depth=1 克隆地址 //只clone最新的代码,不clone相关git文件,
尾声
日后遇到更多的git的tips时,会保持持续的更新。
最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
2018年7月2号,我正式开始了自己的Android工作,为了能够让自己能够好好完成工作,并且能够快速得到技术提升。所以打算以公众号的方式去敦促自己学习,我会把自己日常的学习笔记发布到公众号上,如果可以,共同进步!~