1、玩转Github
想学git,我们首先要有一个Github账号,关于Github是什么,以及怎么注册及使用,git的诞生请看这篇文章。最近关于Github微软又增加了一个打赏的功能,感兴趣的可以看一看。如果你想开通这个打赏的功能,可以通过这个链接https://github.com/sponsors,点击“join the waitlist”,然后填一张表等待审核就行了,之后就可以设置金额、结算日期、收费账户等信息了。
github上的热门项目网址https://github.com/trending
2、Git下载及配置
我们第一次用git或者是新电脑上重新安装git工具的时候,都需要重新配置一下这个工具。
Windows安装git
官网网址https://git-scm.com/downloads下载速度慢,且有可能安装不成功。
附快速下载地址(国内下载站):https://github.com/waylau/git-for-win 。
下载完之后,Windows中你在桌面上或者文件管理器中鼠标右键就可以看见Git Bash here,就是用来打开git bash的。
Linux安装git
linux在终端中,输入sudo apt-get install git
下载完可以用命令git --version
打印当前的git版本验证是否成功。下面正式开始Git的配置。
配置git基本信息
接下来就是不管我们是第一次使用git工具,还是后来换电脑了,还是换成linux系统了,要想使用git都按照下面的方法配置一遍,才可以使用。
安装成功之后,在命令行中敲下如下命令 git config --list
,显示当前的配置信息。
接下来设置提交仓库时的用户名信息 git config --global user.name "张三"
设置提交仓库是的邮箱信息 git config --global user.email "xxxxxxxx@qq.com"
git设置关闭自动换行git config --global core.autocrlf false
为了保证文件的换行符是以安全的方法,避免windows与unix的换行符混用的情况,最好也加上这么一句 git config --global core.safecrlf true
其实这些信息都在一个配置文件中,就在当前用户的主目录下边的.gitconfig文件中,也可以直接打开这个文件cd ~,vim .gitconfig
进行编辑。
git协议及秘钥配置
git有四种协议:Git协议,http协议,本地协议,ssh协议。使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。大部分都是用ssh协议。这个不仅速度快,而且不用每次提交输入密码,可谓是省心省力。
下面就说一下ssh配置过程。(这个协议配置的过程不可缺少,不然就用不了这种协议。)
首先生成 RSA 密钥对 :
ssh-keygen -t rsa -C "xxxxxxxx@qq.com"
注意格式,一定要正确。 ssh和-keygen无空格
此时在用户主目录下就会有一个.ssh隐藏文件,进入该目录有一个id_rsa.pub文件,cat命令查看这个文件,复制下来然后在 github网站添加公钥 ,方法如下
在 Github 网站添加公钥:在右上角头像处点settings进入设置,然后点SSH and GPG keys,进入之后点击New SSH key 粘贴进去,随便给这个秘钥命个名,方便管理就行了。钥匙显示黑色即可。
此时配置就完成了。接下来就可以使用git了。
执行此命令验证是否成功ssh -T git@github.com
成功显示为:Hi XXX! You've successfully authenticated, but GitHub does not provide shell access.
3、先有本地库,后有远程库
创建版本库
可以理解为版本库就是本地文件的一个目录,也叫仓库。可以用git来管理和回退等
创建版本库:找到一个想被管理的文件夹,进入到文件夹里,输入命令git init
,此时git就可以管理这个目录了,并且在文件夹下多出来了一个.git的隐藏文件夹。这个.git就是版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
工作区:就是你在电脑里能看到的目录,比如刚才的文件夹就是一个工作区
第一步:将文件添加到暂存区
当我们想添加文件或者修改文件是需要添加到版本库中的,否则无法被git跟踪管理呀,所以当我们添加或者修改文件时,先要用git add filename
添加到暂存区中,filename为.
的时候代表当前目录下所有文件都添加到暂存区
第二步:将文件提交到分支
git commit -m "message"
,将文件提交到了分支。
添加远程库
我们已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。
首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库,在Repository name填入项目名字,比如我们叫learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库
目前,在GitHub上的这个learngit仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
现在,我们根据GitHub的提示,在本地的learngit仓库下运行命令:
git remote add origin git@github.com:mengchaobbbigrui/learngit.git
请千万注意,把上面的mengchaobbbigrui替换成你自己的GitHub账户名,否则,你在本地关联的就是我的远程库,你以后推送是推不上去的,因为你的SSH Key公钥不在我的账户列表中。
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。下一步,就可以把本地库的所有内容推送到远程库上:
git push -u origin master
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样,从现在起,只要本地作了提交,就可以通过命令:
git push origin master
4、先有远程库,后有本地库
现在,远程库已经准备好了,下一步是用命令git clone克隆一个本地库:
git clone git@github.com:mengchaobbbigrui/learngit.git
可以使用git clone -b branch
克隆指定的分支
5、版本回退
工作区的恢复
使用checkout恢复工作区 git checkout .
(全部修改),git checkout -- file
改回一个文件,工作区--->还没add
add 和 commit 的撤销
git reset HEAD filename 把这个file移除暂缓区,其实就是相当于没用add这个file
git reset --soft HEAD^ ^为最近一次 ^2为上上次 HEAD可以变为指定版本号
--mixed 不删除工作空间改动代码,撤销commit,并且撤销git add .
--soft 不删除工作空间改动代码,撤销commit,不撤销git add .
--hard 删除工作空间改动代码 工作区回退到最近一次commit状态
撤掉add HEAD
撤掉commit HEAD^
6、分支管理
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
或者git switch <name>
创建+切换分支:git checkout -b <name>
或者git switch -c <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
7、多人合作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
git push origin master
如果要推送其他分支,比如dev,就改成:
git push origin dev
抓取分支
多人协作时,大家都会往master和dev分支上推送各自的修改。
现在,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆:
git clone git@github.com:mengchaobbbigrui/learngit.git
当从远程库clone时,默认情况下,只能看到本地的master分支。不信可以用git branch
命令看看
现在,要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:
git checkout -b dev origin/dev
git pull
现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:
git add env.txt
git commit -m "add env"
git push origin dev
已经向origin/dev分支推送了他的提交,如果碰巧你也对同样的文件作了修改,并试图推送:
cat env.txt
env
git add env.txt
git commit -m "add new env"
git push origin dev
推送失败,因为最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:
git pull
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
git branch --set-upstream-to=origin/dev dev
(如果上面用git push -u origin dev,这里应该就不会失败了,也就不用执行这条命令了,个人猜测,未验证)
再pull:
git pull
这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:
git commit -m "fix env conflict"
git push origin dev
8、冲突解决
分支合并有冲突
git status
可以看到哪个文件有冲突,我们就先修改文件,修改好了,再去合并
bug分支修改有冲突
当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交。并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug
幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:git stash
git stash pop
,恢复的同时把stash内容也删了
强行删除未合并的分支
如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>
强行删除。
9、标签管理
命令git tag <tagname>
用于新建一个标签,默认为HEAD,也可以指定一个commit id;
命令git tag -a <tagname> -m "blablabla..."
可以指定标签信息;
命令git tag
可以查看所有标签。
命令git push origin <tagname>
可以推送一个本地标签;
命令git push origin --tags
可以推送全部未推送过的本地标签;
命令git tag -d <tagname>
可以删除一个本地标签;
命令git push origin :refs/tags/<tagname>
可以删除一个远程标签。
10、其他命令
git log
命令显示从最近到最远的提交日志,我们可以看到3次提交,显示我们添加了什么和哈希值。可以用git reset --hard 哈希值
回退
git reflog
查看命令历史,以便确定要回到未来的哪个版本。
git diff HEAD -- readme.txt
命令可以查看工作区和版本库里面最新版本的区别:
git status
命令会立刻告诉你哪些文件变更
11、公司主仓新增分支,如何更新个人本地代码和个人远程仓新分支
本地使用git remote -v
,然后设置远端仓库的地址git remote add 远端仓库名称 远端仓库地址
,例如这样git remote add top ssh://xxxxx
使用git remote -v
查看是否添加成功
创建并切换本地新的分支 git checkout -b 新分支名
拉取远端仓库代码到本地 git pull 远端库名 远端分支名
例如:git pull top branch
推送到个人私库上 git push 远端私库名 远端分支
例如:git push origin branch
子仓
git submodule update --init --remote
git submodule foreach git checkout branch
git submodule foreach --recursive