git fetch和git pull的区别_高频git面试题
ssh keygen
: 生成非对称加密中的 public-key 与 private-key,并把 public-key 扔到 github 上。详情上篇文章 安大虎:服务器基本配置- github新建repository与本地仓库与云仓库的版本管理
- gitignore失效解决方法
- git commit 时出现的问题及解决方法
- git rm 与 rm的区别
- 常用git命令整理
- cherry-pick的使用
- git强制切换至其他分支的方法
- git fetch与git pull的区别及各自使用场景
- git 出现unable to access的时候
- git提交后发现想要回滚到原先版本
- git撤销commit但是未git push的情况(11与12比较相似)
- 如何删除GitHub或者GitLab上的文件夹
- git clone 指定分支
- git 添加tag进行CI/CD
微信核心500人群:群内不定期会有赞助商送书活动,BAT大厂资深大牛定期推送面经与源码分析,各平台大牛优秀文章推荐,更有内推跳槽咨询、视频资源共享、学习资料文章pdf面经网盘资源等等福利。加入我们一起进步。
为了解决知乎活码识别问题,下方的二维码做了持久化处理。扫描二维码添加客服小柠即可加入我们。
公众号:中台架构之家
群内分享每日一题:题目传送门
前端电子书大全:电子书
每日7点贝壳网P7大牛免费基础公开课开讲中
1、ssh keygen
使用ssh原因:虽然 git 可以工作在 ssh 与 https 两种协议上,但为了安全性,更多时候会选择 ssh。
如果采用 https,则每次 git push 都需要验证身份
Permission denied (publickey).
如果没有设置 public key 直接 git clone
的话,会有权限问题
可以使用 ssh -T
测试连通性
$ git clone git@github.com:vim/vim.git
Cloning into 'vim'...
Warning: Permanently added the RSA host key for IP address '13.229.188.59' to the list of known hosts.
Permission denied (publickey). fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.
不过有一个更直接的命令去查看是否有权限
$ ssh -T git@github.com
Permission denied (publickey).
生成一个新的 ssh key
使用 ssh-keygen
可以生成配对的 id_rsa
与 id_rsa.pub
文件
# 生成一个 ssh-key
# -t: 可选择 dsa | ecdsa | ed25519 | rsa | rsa1,代表加密方式
# -C: 注释,一般写自己的邮箱 $ ssh-keygen -t rsa -C "shanyue"
# 生成 id_rsa/id_rsa.pub: 配对的私钥与公钥 $ ls ~/.ssh authorized_keys config id_rsa id_rsa.pub known_hosts
在 github 设置里新添一个 ssh key
在本地服务器中复制 ~/.ssh/id_rsa.pub
中文件内容,并粘贴到github>setting>new sshkey中
$ cat ~/.ssh/id_rsa.pub
在 github 的 ssh keys 设置中:https://github.com/settings/keys
点击 New SSH key
添加刚才的key。
更多图文指引可以参照官方文档:https://help.github.com/cn/articles/adding-a-new-ssh-key-to-your-github-account
设置成功
使用 ssh -T
测试成功, 此时可以成功的面向 github 编程了
2、新建repository
新建后的页面参考如下,注意选择SSH方式,选择HTTPS方式不管你是否添加了sshkey都会让你进行认证
在本地按照第一或第二条记录进行操作即可将本地代码push到github相应的repository中
3、gitignore失效
问题:
在使用git进行版本控制的过程中发现,将想被忽略的文件(文件夹)配置到.gitignore文件中后,实际修改了想被忽略的文件,调用git status查看时,仍然会提示提交这些文件。也就是说实际并没有被忽略
原因:
原因是git ignore只会对不在git仓库中的文件进行忽略,如果这些文件已经在git仓库中,则不会忽略。所以如果需要忽略的文件已经提交到本地仓库,则需要从本地仓库中删除掉,如果已经提交到远端仓库,则需要从远端仓库中删除。删除.gitignore文件才能实际生效。
为什么我增加了 .gitignore 里的规则却没有效果?
这是因为我们误解了 .gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。
之所以你的规则不生效,是因为那些 .log
文件曾经被 Git 记录过,因此 .gitignore
对它们完全无效。这也正是开头那段简短答案所做的事情:
- 从 Git 的数据库中删除对于该文件的追踪;
- 把对应的规则写入 _.gitignore_,让忽略真正生效;
- 提交+推送。
只有这样做,所有的团队成员才会保持一致而不会有后遗症,也只有这样做,其他的团队成员根本不需要做额外的工作来维持对一个文件的改变忽略。
最后有一点需要注意的,git rm --cached
删除的是追踪状态,而不是物理文件;如果你真的是彻底不想要了,你也可以直接 rm
+忽略+提交。
解决:
比较暴力的方法
从远端仓库clone一份代码
使用git rm fileIgnored -r 删除需要被忽略的文件
.gitignore中配置需要被忽略的文件
git add . 然后git commit ;再git push 到远端服务器
这样保证远端服务器上没有需要被Ignore的文件,即使在本地修改这些文件,使用git status查看也不会再有提示了。
较优秀的方法
文件较多
- 删除track的文件 (已经commit的文件)
git rm 要忽略的文件
git commit -a -m "删除不需要的文件"
2.在.gitignore
文件中添加忽略规则
- (1) 在
.gitignore
文件中添加ignore条目, 如:some/path/some-file.ext
- (2) 提交
.gitignore
文件:git commit -a -m "添加ignore规则"
3.推送到远程仓库是ignore规则对于其他开发者也能生效: git push [remote]
文件较少
git rm -r --cached 要忽略的文件
(如:git rm -r --cahced build/*
, 如修改列表中的内容全部是不需要的, 那么你可以使用最最简单的命令搞定git rm -r --cached .
)git add .
git commit -m " commit ....."
git push
push之后其他开发人员pull之后, ignore规则就对其生效了.
注意上传到gitlab中的文件需要手动删除,下次push或pull之后ignore文件便可生效。
4、git commit -a时出现的问题
在使用git commit -a时出现将ignored的文件提交的情况。
示例情况(避免使用git commit -a)
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit
加上 -a
选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤:
$ git status
On branch master Your branch is up-to-date with 'origin/master'.
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: CONTRIBUTING.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks 1 file changed, 5 insertions(+),
0 deletions(-)
提交之前不再需要 git add
文件“CONTRIBUTING.md”了。 这是因为 -a
选项使本次提交包含了所有修改过的文件,但是在提交后会产生ignore中的数据被提交上去的情况(前提是ignore的文件被修改,但是没有add)
5、git rm与rm的区别
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是简单地从工作目录中手工删除文件,运行 git status
时就会在 “Changes not staged for commit” 部分(也就是 未暂存清单)看到:
$ rm PROJECTS.md
$ git status On branch master Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) deleted: PROJECTS.md no changes added to commit (use "git add" and/or "git commit -a")
然后再运行 git rm
记录此次移除文件的操作:
$ git rm PROJECTS.md rm 'PROJECTS.md'
$ git status On branch master Your branch is up-to-date with 'origin/master'.
Changes to be committed: (use "git reset HEAD <file>..." to unstage)
deleted: PROJECTS.md
下一次提交时,该文件就不再纳入版本管理了。 如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 -f
(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删尚未添加到快照的数据,这样的数据不能被 Git 恢复。
另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加 .gitignore
文件,不小心把一个很大的日志文件或一堆 .a
这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用 --cached
选项:
$ git rm --cached README
git rm
命令后面可以列出文件或者目录的名字,也可以使用 glob
模式。比如:
$ git rm log/*.log
注意到星号 *
之前的反斜杠 , 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除
log/
目录下扩展名为 .log
的所有文件。 类似的比如:
$ git rm *~
该命令会删除所有名字以 ~
结尾的文件。
6、常用git命令
针对摆脱了可视化工具的版本管理工具git的基础知识及命令如下
目前可知的主要环境细分如下:
release(线上):发布至网络后,对重要的release进行版本发布
beta(预发布):模拟生产环境,测试各种数据的正确性
test(测试):主要对代码的鲁棒性进行测试
develop(开发):细分到个人的开发分支,所有人开发后合并到的主分支
目前我们的小团队中只细分出开发与线上两个分支,很多的测试步骤已经在开发的过程中走过。当然随着团队技术的不断进步,我们能做的将越来越多。
将代码通过git上传至coding或码云的代码仓库,或者是本地的代码仓库。
下载git的内容,这里不做记录,仅从创建本地仓库开始
git 入门级命令
安装完git要配置以下操作
git config --global user.name "你的名字或昵称"
git config --global user.email "你的邮箱"
配置完后要进行本地密码与账户名的保存
git config --global credential.helper store
此时会在本地保存一个文本文档,用于记录账户与密码,以便以后不用每次操作命令都输入密码了。
进入想要上传代码仓库的项目文件夹,输入以下命令行:
git init
执行完在本文件夹下生成.git文件,生成了一条文件树,同时该文件为隐藏文件,隐藏文件的查看方法:
ls -a
接下来我们需要将文件树中的内容commit到本地仓库中去,输入命令:
git add .
准备好当前文件夹下的全部文件,通过以下命令添加:
git commit -m 'description'
description中添加备注信息,记录此次提交内容
随后即可将本地代码提交到远程仓库中去了,不过前提是必须确定服务器地址及分支:
git remote add origin https://git.coding.net/username/projectname.git
随后即可推送
git push origin master
推送到master分支下
但是在push前最好使用pull来拉取下最新资源。避免冲突
git pull origin master
origin为remote的远程代码仓库路径,master为拉取的目标分支。
同步本地的仓库与远程仓库的名称一致。
新建分支命令
git branch 分支名
切换分支
git checkout 分支名
然后在新分支中也要走一遍git流程才能够将本地仓库的内容push到远程仓库中去
git add .
git commit -m "提交的信息"
git remote add origin 远程仓库地址
git pull origin 分支名
git push -u origin 分支名
但是有时某个分支的命名与远程仓库中的分支冲突时我们需要将本地仓库中的分支删除掉,以下是删除本地分支与远程分支的基本步骤:
在在release20181018分支上,想删除release20181018分支
1 先切换到别的分支: git checkout dev20180927
2 删除本地分支: git branch -d release20181018
3 如果删除不了可以强制删除,git branch -D release20181018
4 有必要的情况下,删除远程分支:git push origin --delete release20181018
5 在从公用的仓库fetch代码:git fetch origin release20181018:release20181018
6 然后切换分支即可:git checkout release20181018
在push的过程中必须保持本地与远程分支的名称一致性,否则会报错。
reference:Git - Book
7、cherry-pick的使用
cherry-pick是Git里对commit操作很好的一个指令,比如想把test分支中的其中多个commit merge到master,那么你需要挑你所需要的commit合到master,这时候就用cherry-pick来捡。
|
| C3
| |
C1 C2
| | test
| /
| /
master
想将test分支中的C2 commit合并到master分支,丢弃C3的修改。 直接merge会把C3也合并进去,这时用git cherry-pick可以解决问题
- 先用git log查看,C2 commit的id,复制下来
- git checkout 到master分支下
- git cherry-pick <C2_id>
如果cherry-pick过程中没有出现冲突的话,就是完成了合并,参考下方内容
|
C4
|
| C3
| |
C1 C2
| | test
| /
| /
master
如果出现冲突,按以下的流程进行操作即可
- 先解决冲突
- git add 将解决了冲突的文件添加到暂存区
- git cherry-pick --continue
8、git强制切换至其他分支
分支基本操作
git branch //查看本地所有分支
git branch -r //查看远程所有分支
git branch -a //查看本地和远程的所有分支
git branch <branchname> //新建分支
git branch -d <branchname> //删除本地分支
git branch -d -r <branchname> //删除远程分支,删除后还需推送到服务器
git push origin:<branchname> //删除后推送至服务器
git branch -m <oldbranch> <newbranch> //重命名本地分支
强制切换分支
git checkout -f develop
//Git 一个分支完全替换成另一个分支
git checkout master//切换到旧分支
git reset --hard develop//将本地的旧分支master重置为develop
git push origin master --force//在推送到远程仓库
9、git fetch&git pull详解
git fetch的意思是将远程主机的最新内容拉到本地,用户再检查无误后再决定是否合并到工作本地分支中
git pull 是将远程主机中的最新内容拉取下来后直接合并,即:git pull = git fetch+git merge,这样可能会产生冲突,需要手动解决。
git fetch的用法
git fetch <远程主机名>//该命令将远程主机的更新全部取回本地
如果只想取回特定的分支更新,指定分支名即可
git fetch <远程主机名> <分支名>//之间有空格
可以使用
git log -p fetch_head
查看刚取回后的更新信息
git pull的用法
git pull <远程主机名> <远程分支名>
pull后的操作是拉取与合并一起操作
git pull
的过程可以理解为:
git fetch origin master //从远程主机的master分支拉取最新内容
git merge FETCH_HEAD //将拉取下来的最新内容合并到当前所在的分支中
即将远程主机的某个分支的更新取回,并与本地指定的分支合并,完整格式可表示为:
$ git pull <远程主机名> <远程分支名>:<本地分支名>
如果远程分支是与当前分支合并,则冒号后面的部分可以省略:
$ git pull origin next
10、git 出现unable to access的时候
fatal: unable to access 'https://gitlab.momenta.works/DataOps/data/tropo-web/': SSL certificate problem: certificate has expired
我们需要输入git config http.sslVerify false
全局设置:git config --global http.sslVerify false(不推荐设置)
11、git在pull后想要回滚到之前版本
git reflog master (查看本地master分支历史变动纪录)
使用git reset --hard <COMMIT_ID> (恢复到之前位置)
或git reset --hard master@{1}
12、git撤销commit但是未git push的情况
找到上次git commit的id
git log//查看列表里的内容并直接复制commit id
情况一:执行撤销操作,同时将代码恢复到该commit_id之前的代码提交状态
git reset --hard commit_id
情况二:完成commit命令的撤销,但是不对代码修改进行撤销,可以直接通过git commit 重新提交对本地代码的修改
git reset commit_id
13、如何删除GitHub或GitLab上的文件夹
假设小明有一天不小心把本地仓库的一个文件夹A推送到了远程GIT服务器(例如:github,gitlab,gitee)上,此时想删除远程仓库的文件夹A,但是本地又不想删除。小明于是去问小红,怎么办?小红不假思索的说,github,gitlab 不是可以删除吗?你直接在远程服务器上操作呀。小明告诉小红,远程操作只能操作单个文件,无法删除文件夹,你可不会傻到一个一个文件去删除。小红说,那怎么办呢?
解决办法
重点在于git push -u
方法一
这里以删除 .setting 文件夹为案例
git rm -r --cached .setting #--cached不会把本地的.setting删除
git commit -m 'delete .setting dir'
git push -u origin master
方法二
如果误提交的文件夹比较多,方法一也较繁琐
直接修改.gitignore文件,将不需要的文件过滤掉,然后执行命令
git rm -r --cached .
git add .
git commit
git push -u origin master
14、git clone指定分支
git clone 不指定分支
git clone http://10.1.1.11/service/tmall-service.git
git clone 指定分支
git clone -b dev_jk http://10.1.1.11/service/tmall-service.git
需要注意-b branch_name在https地址之前
15、git 添加tag进行CI/CD
查看commit的版本编号
git reflog branch_name
添加标签
/// 查看标签
// 打印所有标签
git tag
// 打印符合检索条件的标签
git tag -l 1.*.*
// 查看对应标签状态
git checkout 1.0.0
/// 创建标签(本地)
// 创建轻量标签
git tag 1.0.0-light
// 创建带备注标签(推荐)
git tag -a 1.0.0 -m "这是备注信息"
// 针对特定commit版本SHA创建标签
git tag -a 1.0.0 0c3b62d -m "这是备注信息"
/// 删除标签(本地)
git tag -d 1.0.0
/// 将本地标签发布到远程仓库
// 发送所有
git push origin --tags
// 指定版本发送
git push origin 1.0.0
/// 删除远程仓库对应标签
// Git版本 > V1.7.0
git push origin --delete 1.0.0
持续更新中
Happy Hacking~~