
提交代码到GitHub
- SSH
SSH是一种网络协议,用于计算机之间的加密登录。目前是每一台 Linux 电脑的标准配置。而大多数 Git 服务器都会选择使用 SSH 公钥来进行授权,所以想要在 GitHub 提交代码的第一步就是要先添加 SSH key 配置。 - 生成SSH key
Linux 与 Mac 都是默认安装了 SSH ,而 Windows 系统安装了Git Bash 应该也是带了SSH的。大家可以在终端(win下在Git Bash里)输入 ssh 如果出现以下提示证明你本机已经安装SSH, 否则请搜索自行安装下。
紧接着输入ssh-keygen -t rsa
来指定rsa
算法生成密钥,接着连续三个回车键(不需要输入密码),然后就会生成两个文件id_rsa
和id_rsa.pub
,而id_rsa
是密钥,id_rsa.pub
就是公钥。这两文件默认分别在如下目录里生成:
Linux/Mac系统在 ~/.ssh 下,
win系统在/c/Documents and Settings/username/.ssh下,都是隐藏文件,相信你们有办法查看的。
在Linux/Mac系统中,使用如下命令:
cd ~/.ssh
gedit id_rsa.pub
在Windows系统下,设置显示隐藏文件,可以使用 EditPlus或者Sublime打开复制就行了。
接下来要做的是把id_rsa.pub
的内容添加到GitHub上,这样你本地的id_rsa
密钥跟GitHub上的id_rsa.pub
公钥进行配对,授权成功才可以提交代码。
- GitHub 上添加 SSH key
第一步先在GitHub上的设置页面,点击最左侧SSH and GPG keys :ssh_key.png 然后点击右上角的New SSH key 按钮,然后将
id_rsa.pub
公钥文件里的内容复制粘贴进Key那一栏,Title 那栏不需要填写,点击 Add SSH key按钮就ok了。
SSH key 添加成功之后,输入ssh -T git@github.com
进行测试,查看是否添加成功。一般没问题,有问题Google解决方案。 - Push & Pull
Push
:直译过来就是「推」的意思,什么意思呢?如果你本地代码有更新了,那么就需要把本地代码推到远程仓库,这样本地仓库跟远程仓库就可以保持同步了。
代码示例:
git push origin master
意思就是把本地代码推到远程 master 分支。
Pull
:直译过来就是「拉」的意思,如果别人提交代码到远程仓库,这个时候你需要把远程仓库的最新代码拉下来,然后保证两端代码的同步。
代码示例:
git pull origin master
意思就是把远程最新的代码更新到本地。一般我们在 push
之前都会先 pull
,这样不容易冲突。
- 提交代码
添加 SSH key 成功之后,我们就有权限向 GitHub上我们自己的项目提交代码了,而提交代码有两种方法:
方式一: Clone自己在Github上的项目,在本地进行修改然后上传到Github。
以我在github上创建的Git_learn项目为例。
首先执行如下命令将Git_learn 项目clone到本地:
git clone https://github.com/JwDong2019/Git_learn.git
此时该项目本身就已经是一个git仓库了,不需要执行 git init
进行初始化,而且甚至都已经关联好了远程仓库,我们只需要在Git_learn这个目录下任意修改或者添加文件,执行文件操作后记得使用git add 文件(夹)
将其添加进git 仓库,然后执行git commit -m '提交注释'
,之后就可以执行:git push origin master
。在提交代码之前先要设置下自己的用户名与邮箱(可以在文件操作一开始就设置),这些信息会出现在所有的 commit 记录里,执行以下代码就可以设置:
git config --global user.name"JwDong2019"
git config --global user.email"jwdong2015@163.com"
具体操作步骤可见下图:


git add file
,git commit -m '提交注释'
,最后在使用git push origin master
将代码上传到github。代码示例:
touch dog.py
git add dog.py
git commit -m 'creat dog.py'
touch duck.py
git add duck.py
git commit -m 'creat duck.py'
git push origin master
结果如下:

方式二:关联本地已有的git仓库,并将其提交到Github上
以上一篇教程中本地创建的git_learn仓库为例。
第一步是在Github上创建一个项目
第二步是将本地的项目与Github上的项目进行关联
mkdir git_learn (创建文件夹git_learn)
cd git_learn (切换到git_learn目录)
touch git.md (新建git.md文件)
git init #初始化git仓库
##**设置用户名和邮箱**##
git config --global user.name"JwDong2019"
git config --global user.email"jwdong2015@163.com"
git status #查看状态
git add git.md
git commit -m 'add git.md'
git remote add origin https://github.com/JwDong2019/Git_learn.git
#添加一个远程仓库,他的地址是https://github.com/JwDong2019/Git_learn.git ,而origin是给这个项目的远程仓库起的名字
git pull origin master #上传代码到github之前需要先pull,否则报错
git push origin master #上传代码Github仓库
项目名(此处为origin)可以随便取,只不过大家公认的只有一个远程仓库时名字就是 origin ,为什么要给远程仓库取名字?因为我们可能一个项目有多个远程仓库,比如 GitHub 一个,比如公司一个,这样的话提交到不同的远程仓库就需要指定不同的仓库名字了。可以使用git remote -v
命令查看我们当前项目有哪些远程仓库。
此时Github仓库如下:

注:上传本地git仓库到Github一定要记得获取Github上的代码,保持两端同步。可以使用git pull origin master
命令。
注:
git push origin #表示将当前分支推送到origin主机的对应分支,如果当前分支只有一个追踪分支,那么主机名都可以省略。
git push #如果当前分支与多个主机存在追踪关系,那么这个时候-u选项会指定一个默认主机,这样后面就可以不加任何参数使用git push
git push -u origin master #表示将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了
-
删除代码
通过上述两种方式我们可以轻松地管理本地与Github上的代码了,如果我们想删除Github上的代码,并重新提交,可以进行如下操作:
git pull origin master # 将远程仓库里面的项目拉下来
git rm -r git.md # 删除git.md文件
git commit -m 'delete git.md' #删除完记得提交,添加操作说明
git push origin master # 将本次更改更新到github项目上去
Git 进阶
- 用户名和邮箱
我们知道我们进行的每一次commit都会产生一条log,这条log标记了提交人的姓名与邮箱,以便其他人方便的查看与联系提交人,所以我们在进行提交代码的第一步就是要设置自己的用户名与邮箱。执行以下代码:
git config --global user.name"JwDong2019"
git config --global user.email"jwdong2015@163.com"
以上进行了全局配置,当然有些时候我们的某一个项目想要用特定的邮箱,这个时候只需切换到你的项目,以上代码把 --global
参数去除,再重新执行一遍就ok了。
PS:我们在 GitHub 的每次提交理论上都会在主页的下面产生一条绿色小方块的记录,如果你确认你提交了,但是没有绿色方块显示,那肯定是你提交代码配置的邮箱跟你 GitHub 上的邮箱不一致,GitHub 上的邮箱可以到 Setting -> Emails里查看。
- alias 设置命令别名
代码如下:
git config --global alias.co checkout #别名
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global alias.psm 'push origin master'
git config --global alias.plm 'pull origin master'
之后经常用到的git push origin master 和 git pull origin master 直接就用 git psm 和 git plm 代替了,是不是很方便?
Tips: 更改git log日志的显示方式。
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(blue)<%an>%Creset' --abbrev-commit --date=relative"
显示如下:

git log
命令可参考git log命令全解析,打log还能这么随心所欲!
- 其他配置
Git默认编辑器是GUN nano编辑器。使用git commit
命令可以进入GUN nano编辑模式,在这里可以添加你的commit imformation 然后ctrl+o,回车保存,再ctrl+x退出。如果不熟悉可以改成其他编辑器,比如我喜欢用gedit或者vim。
更改编辑器
git config --global core.editor "gedit" # 设置Editor使用gedit
开启Git着色
git config --global color.ui true
显示中文文件名
git config --global core.quotepath false #设置显示中文文件名
-
diff 查看代码改动情况
值得一提的是直接输入git diff
只能比较当前文件和暂存区文件差异,执行git add
命令将文件存进暂存区。未执行git add
操作之前使用git diff
命令只能查看文件内容的最终版本。
git_diff.png 当然跟暂存区做比较之外,他还可以有其他用法,如比较两次 commit 之间的差异,比较两个分支之间的差异,比较暂存区和版本库之间的差异等,具体用法如下:
git diff <$id1> <$id2> # 比较两次提交之间的差异
git diff <branch1>..<branch2> # 在两个分支之间比较
git diff --staged # 比较暂存区和版本库差异
- checkout
我们知道 checkout 一般用作切换分支使用,比如切换到 develop 分支,可以执行:
git checkout develop
但是 checkout 不只用作切换分支,他可以用来切换tag,切换到某次commit,如:
git checkout v1.0
git checkout ffd9f2dd68f1eb21d36cee50dbdd504e95d9c8f7 # 后面的一长串是commit_id,是每次commit的SHA1值,可以根据 `git log` 看到
除了有“切换”的意思,checkout 还有一个撤销的作用,举个例子,假设我们在一个分支开发一个小功能,刚写完一半,这时候需求变了,而且是大变化,之前写的代码完全用不了了,好在你刚写,甚至都没有 git add
进暂存区,这个时候很简单的一个操作就直接把原文件还原:
git checkout a.md
注:checkout命令只能撤销还没有add进暂存区的文件。
- stash
设想一个场景,假设我们正在一个新的分支做新的功能,这个时候突然有一个紧急的bug需要修复,而且修复完之后需要立即发布。当然你说我先把刚写的一点代码进行提交不就行了么?这样理论上当然是ok的,但是这会产品垃圾commit,原则上我们每次的commit都要有实际的意义,你的代码只是刚写了一半,还没有什么实际的意义是不建议就这样commit的,那么有没有一种比较好的办法,可以让我暂时切到别的分支,修复完bug再切回来,而且代码也能保留的呢?
这个时候stash
命令就大有用处了,前提是我们的代码没有进行commit
,哪怕你执行了add
也没关系,我们先执行命令:
git stash
把当前分支所有没有 commit
的代码先暂存起来,这个时候你再执行 git status
你会发现当前分支很干净,几乎看不到任何改动,你的代码改动也看不见了,但其实是暂存起来了。执行
git stash list
你会发现此时暂存区已经有了一条记录。
这个时候你可以切换会其他分支,赶紧把bug修复好,然后发布。之后一切都解决了,你再切换回来继续做你之前没做完的功能,但是之前的代码怎么还原呢?
git stash apply
你会发现你之前的代码全部又回来了,就好像一切都没发生过一样,紧接着你最好需要把暂存区的这次stash
记录删除,执行:
git stash drop
就把最近一条的 stash
记录删除了,是不是很方便?其实还有更方便的,你可以使用:
git stash pop
来代替 apply
命令, pop
跟 apply
的唯一区别就是 pop
不但会帮你把代码还原,还自动帮你把这条 stash
记录删除,省的自己再 drop
一次了,为了验证你可以紧接着执行git stash list
命令来确认是不是已经没有记录了。
清空所有暂存区的记录
git stash clear
drop
是只删除一条,当然后面可以跟 stash_id
参数来删除指定的某条记录,不跟参数就是删除最近的,而 clear
是清空。
- merge & rebase
我们知道merge
分支是合并的意思,我们在一个featureA分支开发完了一个功能,这个时候需要合并到主分支master上去,我们只需要进行如下操作:
git checkout master
git merge featureA
其实 rebase 命令也是合并的意思,上面的需求我们一样可以如下操作:
git checkout master
git rebase featureA
rebase
跟 merge
的区别你们可以理解成有两个书架,你需要把两个书架的书整理到一起去。
第一种做法是 merge
,比较粗鲁暴力,就直接腾出一块地方把另一个书架的书全部放进去,虽然暴力,但是这种做法你可以知道哪些书是来自另一个书架的;
第二种做法就是 rebase
,他会把两个书架的书先进行比较,按照购书的时间来给他重新排序,然后重新放置好,这样做的好处就是合并之后的书架看起来很有逻辑,但是你很难清晰的知道哪些书来自哪个书架的。
只能说各有好处的,不同的团队根据不同的需要以及不同的习惯来选择就好。
更多Git操作可参考廖雪峰的Git教程
本系列内容转载总结自原创作者stormzhang,其
个人博客: http://stormzhang.com
GitHub: https://github.com/stormzhang
知乎: stormzhang
微博: googdev
网友评论