实操学Git
修改几遍,还是觉得做的不够清晰明了。期望够精简,但是又感觉好多不说会让人看不明白。如果有看着不舒服,不明白还希望留言告诉我。
一、前期准备
安装Git和创建版本库就不再赘述,网上随便一查就有。这里主要讲述操作远程仓库和分支管理。其实GitHub,Gitee,GitLab等操作都大同小异,这里就以GitHub为例。如果想用自己的服务器搭建一个代码仓库,可以尝试GitLab,参考我的另一篇文章:云服务器搭建GitLab及解决服务器卡顿问题。但是这个耗费资源较多,小的服务器带起来很吃力。可以尝试gogs
,这是一个小而轻的git管理仓库。
-
创建GitHub账户
没啥,注册个呗。
-
添加SSH秘钥
在git命令行工具中,运行下列命令,邮箱输入自己的:
ssh-keygen -t rsa -C "email@example.com"
然后会出现下面的运行界面
然后根据提示的地址找到 id_rsa.pub文件,打开把里面内容同步到远程仓库就可以了(如下图)。这里建议没啥机密就不用设置密码了,直接回车。因为忘记了密码很麻烦。😒
- 本地全局设置,不然没有权限操作远程仓库
git config --global user.name "你的用户名" git config --global user.email "你的邮箱" # 可以yong vim 工具在 ~/.gitconfig中查看设置的全局信息
二、仓库管理
新建仓库
在GitHub 中new Repository
忽略特殊文件
忽略文件的原则是:
忽略操作系统自动生成的文件,比如缩略图等;
忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的
.class
文件忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
.gitignore语法规范:
- 空行或是以#开头的行即注释行将被忽略。
- 可以在后面添加正斜杠/来忽略文件夹,例如build/即忽略build文件夹
- 可以使用!来否定忽略,即比如在前面用了*.apk,然后使用!a.apk,则这个a.apk不会被忽略。*
- * 用来匹配零个或多个字符,如*.[oa]忽略所有以".o"或".a"结尾,*忽略所有以结尾的文件(这种文件通常被许多编辑器标记为临时文件);[]用来匹配括号内的任一字符,如[abc],也可以在括号内加连接符,如[0-9]匹配0至9的数;?用来匹配单个字符。
# 忽略 .a 文件
*.a
# 但否定忽略 lib.a, 尽管已经在前面忽略了 .a 文件
!lib.a
# 仅在当前目录下忽略 TODO 文件, 但不包括子目录下的 subdir/TODO
/TODO
# 忽略 build/ 文件夹下的所有文件
build/
# 忽略 doc/notes.txt, 不包括 doc/server/arch.txt
doc/*.txt
# 忽略所有的 .pdf 文件 在 doc/ directory 下的
doc/**/*.pdf
三、操作仓库
现在描述的都是不考虑其他分支的情况下进行的操作,也就是在origin下只有一个master的情况。
可以先了解一个命令:
git status
。这个可以查看仓库的状态,多查看可以比较清楚每一步做了什么,成功了没有。
clone远程仓库
注意克隆到本地的地址不要与之前操作的仓库在同一个目录下
git clone git@xxx.com:xxx/xxx.git
初始化本地仓库
有时候我们是在本地写好了,想推送到远程新建的仓库,就可以采用如下的方法。首先要进入项目文件夹内,写好 .gitignore
文件。
- 初始化本地仓库
git init
- 绑定远程仓库
git remote add origin git@xxx.com:xxx/xxx.git
# 这个执行过后,git会将远程仓库的名称设置为origin
- 需要先拉取远程新建的仓库,不然会引起冲突
git pull origin
这里有些许不一样,下面的推送等就是完全一样的了
推送
在本地做好修改,推送到远程仓库。
- 将文件添加到暂存区中并提交
# 添加
git add .
# 这句话意义是 git add [<filepattern>]
# 这里 . 表示当前文件夹,添加当前文件夹内所有的文件,并且是递归式地添加(包括其子文件内的文件)
# 提交
git commit -m "这是记录一行提交信息的用法"
# 如果需要详细记录信息,就请直接执行:
git commit
# 然后会弹出许多提示信息,不用管。在最后 空白行记录提交信息,格式如下:
# 第一行:用一行文字简述提交更改的内容,相当于一个标题
# 第二行:空行
# 第三行及以后:记录详细内容
- 查看提交日志(可有可无,但是建议查看一下本次提交与上次有什么区别,避免不必要的错误)
git log
- 推送至远程仓库(关于分支操作,下一条再介绍)
# 推送至master分支
git push -u origin master
# -u 参数可以在推送的同时将origin的master分支设置为当前分支的upstream(上游),这样在git pull 获取内容时,本地分支就可以直接从master=分支过去内容,不必添加参数。
# -f 可以强制推送,但是不建议使用
四、分支管理
创建与合并分支
master是Git默认创建的分支,因此基本上所有的开发都是以这个分支为中心进行的。不同的分支中可以进行不同的作业,待完成之后再与master合并。
主干分支与特性分支
- 主干分支:通常会master分支作为主干分支使用。也是特性分支的原点和合并的终点。主干分支可以配置在正式的环境中,也可以利用标签等创建版本信息,同时管理多个版本发布。
- 特性分支:是集中实现单一特性,除此之外不进行任何作业的分支。这样的话,master可以随时提供给别人看,开发者也可以放心的从master创建新的分支。
创建分支
- 显示分支
git branch
# 执行后分支的左侧有 * 的表示我们当前所在的分支。
- 创建、切换分支
git checkout -b 新分支
# 连续执行下面2条代码的效果是一样的。
git branch 新分支 # 创建
git checkout 新分支 # 切换
- 切换分支
# 上面已经提到切换分支的命令
git checkout 分支名
# 切换回上一个分支
git checkout -
合并分支
- 合并分支前,需要切换到主干分支master中。然后执行下面的命令合并分支。
- 合并分支
git merge 分支
# 为了在历史记录中明确记录下本次的分支合并,我们需要创建合并并提交。因此需要加上 --no-ff 参数,即:
git merge --no-ff 分支
- 以图表的形式查看分支
git log --graph
删除分支
git branch -d 分支
五、解决冲突
冲突的时候可以用git status
命令查看冲突的文件,查看文件内容可以看到用<<<<<<<
,=======
,>>>>>>>
标记处不同的分支的内容。=======
以上部分是当前HEAD的内容,以下部分是要合并的分支中的内容,在这里手动解决冲突。冲突解决后再进行提交。
六、多人协作
操作都是前面介绍的基础操作,但是要注意一些细节。
了解基本流程与分支协作的注意项
- 先从远程库clone,然后本地只管写代码,推送的时候切换到dev分支,进行添加,提交,push操作。
master
是主分支,不做频繁改动,平常开发都在dev
分支中进行。
具体流程与命令
先了解几个命令
-
git status
: 查看仓库的状态,多用这个命令可以了解工作树与仓库的状态,可以一定程度上避免冲突。 -
git log
: 查看提交日志 -
git lpg --pretty=short
: 只显示提交信息的第一行 -
git log -p
,git log -p 文件
:显示文件的改动 -
git log --graph
其中
git log
,git log --graph
用的较多 -
git branch
:查看分支 -
git diff
:查看更改前后差别
获取远程仓库
git clone 远程仓库地址
* 执行后会默认处于master主分支下,
git branch -a # 查看所有分支
git checkout dev # 切换到 dev 分支下
抓取分支
git pull # 拉取下来
git branch # 查看当前分支
git checkout 分支名 # 切换分支
这时就可以在分支上进行修改,并时不时的push到远程。
推送分支
推送时要指定本地分支,这样Git就会把该分支推送到远程库对应的远程分支上了。
git push origin 分支
注意,并不是所有的本地分支都需要推送,详情:
master
分支是主分支,因此要时刻与远程同步;- 开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
- bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
- 其他分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
冲突
如果其他成员已经向分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送,那么就会冲突。
解决办法:
- 先
git pull
把最新的提交从远程分支上抓取下来,然后在本地合并,解决冲突后再推送。可能git pull
也失败了,像这样 👇
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> dev
原因是没有指定本地分支与远程分支的链接,根据最后一行的提示,设置链接:(dev是这里使用的分支名)
git branch --set-upstream-to=origin/dev dev
然后git pull
抓取分支,若有冲突,和之前解决办法是一样的。
七、回退历史版本
可以先使用git log
命令显示从近到远的提交日志。如果嫌信息太多,可以使用git log --pretty=online
-
回退上一个版本
git reset --hard HEAD^
2, 回退到指定版本
可以根据commit id进行回退
git reset --hard ee881
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
- 回退后,后悔了,想恢复到新版本
git reflog
# 这个命令可以查看你的命令记录,就可以查找 commit 进行回退了。
八、删除远程仓库的某个文件或文件夹
删除文件
这个好操作,直接点进去,右上角有操作按钮,点删除按钮就可以.
删除文件夹
在远程仓库上无法做到这一点,可以pull到本地之后,删除后再push。
# 这里是已经绑定过远程仓库了
git pull progin master
dir # 查看文件夹
git rm -r --cached 文件夹名字
# 注意.开头的文件夹,只用dir是看不到的,要是想删除的话别漏了
git commit -m "删除了无用文件夹"
git push -u origin master # push到远程仓库去
注意:这里的操作对本地文件夹没有影响,可以放心操作。