Git基本使用以及如何向开源项目提交PR(常见问题整理-超实用)
GitHub常用操作问题GitHub clone到本地太慢,经常失败怎么办?如何同官方的仓库保持同步呢?如何向开源项目提交PR?还有其他各种实践问题尽在本文中逐个解答
文章目录
Git基本使用以及如何向开源项目提交PR
目标
- 非常快速的和fork的源仓库保持同步
- 修改代码之后,方便的、快速的提交代码到fork的仓库,并向原仓库提交PR
- 掌握在gitee和GitHub之间快速切换
- 掌握标准的贡献开源的步骤
Git 基本操作
- GitHub上fork一个项目
- 克隆到本地
git clone git@github.com:jacksparrow414/hello-world.git
- 新建一个名字为develop的分支,checkout -b 新建分支并切换到该分支
git checkout -b develop
- 在develop分支修改代码
- 提交暂存
git add .
如果提交到暂存区的文件想要移出暂存区怎么处理?
可以使用下面的命令
git reset HEAD 文件名
或者
git rm --cached 文件名
- 提交到本地仓库,-a代表all,将暂存区的所有文件提交,-m 是提交信息的简要说明
git commit -a -m 'add message'
提交之后,发现文件少提了一个,或者注释信息写错了,又或者codereview没过,怎么处理?
# 修改上一次的提交信息
git commit --amend -m 'modify message'
如果想要修改已经commit的作者信息,可使用如下方法
git rebase -i 目标commit的前一个commit的version number
#在交互页面,目标commit的前面选择edit,:wq 保存
git commit --amend --author="username jack@email.com"
git rebase --continue
# 修改完毕,强制覆盖远程分支
git push --force origin
如果修改多个提交时按上面三个步骤重复操作即可,或者使用git-filter-repo进行批量修改
git rebase默认不能修改root提交,也就是第一个提交,如果想要修改第一个提交,可以使用
git rebase -i --root
# 将忘记提交的文件,例如:忘记提交test.txt文件。 git add test.txt之后
git commit --amend test.txt
# 此时会调出vim编辑器页面,如果想要修改提交信息,则修改之后,:wq保存退出即可
# 如果想使用上次的提交信息,则可以下面这样写
git commit --amend --no-edit test.txt
# 此时 git log查看两次提交最终呈现为一个提交
# 如果codereview没过,不需要abandon,则修改文件之后,采用上面两行任意一种方式之后,
git push
- 推送到GitHub上,有下面几种写法
-
第一种写法:将本地develop分支推送到远程,远程会自动匹配develop这个分支的名字,如果没有,则新建
格式: git push origin 远程分支名字
git push origin develop
git push origin develop:
以上两个命令相当于
git push origin develop:refs/heads/develop
注意:这种写法可以在develop分支上对master上的commit进行push
写法如下:
git push origin master
虽然极其不鼓励此种做法,但是可以了解下
-
第二种写法:将当前的HEAD所在的分支提交到远程,如果没有明确远程分支,则还是默认找当前的分支,没有则新建
格式: git push origin HEAD:refs/heads/远程分支名
origin 是远程源仓库的别名,只有一个的时候,默认为origin,如果需要推送到不同的源,则更换origin为目标名字。
可以使用
git remote -v
查看添加了哪些远程仓库
注意因为这里指定了HEAD,HEAD所在的分支就是本地的分支,也就说,这个命令只能push HEAD所在的分支,想要在develop分支push master分支上的commit,除非切换到master分支上,使HEAD位于master上,或者使用第一中方式
git push origin HEAD:refs/heads/develop
git push origin HEAD
对于gerrit来说,如果需要codereview,则不能直接推送到远程,则需要下面这样写
git push origin HEAD:refs/for/develop
-
第三种方式
不加任何分支名字,默认直接向远程推送当前分支名,远程没找到,则新建分支
在第一次向当前分支的远程分支推送时,如果不设置,则下面的命令报错
git push --set-upstream origin develop
以后每次提交在该推送远程时,只需要
git push
git push origin
两种方式效果一样
-
建议建议平时可以使用第三种方式,更简单
-
推送到个人远程分支之后,pull一下
-
直接拉取默认远程仓库origin的远程分支对应的本地分支,如果远程仓库不止origin一个,则想要从哪个远程仓库拉取,直接替换origin名字即可
git pull
git pull origin
-
拉取远程develop分支合并到当前分支
git pull origin develop
拉取另一个远程仓库upstream的master分支并合并到到当前分支
git pull upstream master
注意 这里的origin代表远程的源仓库,默认是叫origin,可以有多个远程的源仓库,可以使用
git remote -v
查看本地都有哪些远程的源仓库
-
-
合并develop分支的某一个提交到master分支
切换到master分支
git checkout master
查看最近的git操作日志
git reflog
找到develop分支上的一处提交
# commitId就是git reflog中找到的develop的commitId git cherry-pick commitID
如果想要cherry-pick多个提交怎么办?可以执行一个区间
# 区间为(A,B],不包括A,但包括B git cherry-pick commitIdA..commitIdB
则会把commitIdA和commitIdB的区间内的提交都会pick到当前分支。
# 区间为[A,B]既包括A,又包括B git cherry-pick commitIdA^..commitIdB
也可以在idea上,找到Git->选择要cherry-pick的分支的提交,然后右键cherry-pick即可。例如,将dev分支上的某一个/几个提交,cherry-pick到当前master分支
-
回退HEAD指针到前几步
-
保留本地提交信息
# HEAD~N,表示回到N步,N是数字 git reset --soft HEAD~2
-
不保留本地提交信息
git reset --hard HEAD~2
-
-
如果已经推送到远程了,发现提交的文件有问题,想要撤销这次提交。使用git revert 命令。revert命令会生成一次新的提交历史,来表明这次提交时撤销某一次的提交
# commitId是想要撤销的某一次提交的commitId git revert commitId git push
-
如果本地曾经修改过git的user.name,但是发现修改完毕之后没有效果,可以使用
git commit --amend --reset-author
Git 其他设置以及常见问题
warning Delete ␍
prettier/prettier
出现这个问题一般是在前端项目中,项目里有eslint。在window系统中,clone代码下来,会自动把换行符LF(linefeed character) 转换成回车符CRLF(carriage-return character)。这时候我们本地的代码都是回车符
关掉自动转换设置
git config --global core.autocrlf false
修复
yarn run lint --fix
即可正常构建、启动项目
GitHub常用操作
问题
GitHub clone到本地太慢,经常失败怎么办?
在GitHub上fork项目到自己的仓库,当项目很大时,由于GitHub访问速度慢,导致clone不到本地。
可以选择使用gitee同步,然后
git clone gitee仓库地址
克隆到本地,添加GitHub的个人仓库地址为另一个远程源
格式: git remote add 自定义一个名字 远程仓库地址
远程仓库地址:可以在GitHub个人该项目的仓库下clone,选择HTTPS,复制即可
git remote add person_repo https://github.com/xxxx
此时默认的origin是gitee上的,如果仅仅是想快速从gitee上下载项目,但是origin对应的源想要是GitHub上的个人仓库怎么处理呢?
git remote set-url origin https://github.com/xxxx
将origin的url设置为GitHub上的自己fork仓库的地址,而不是gitee上的
设置成功之后,则把上一步相同的远程源(person_repo)删掉
git remote remove person_repo
查看本地分支已经关联的远程分支
git branch -vv
那么如何同官方的仓库保持同步呢?
-
第一种方法,GitHub个人fork仓库页面,如图
-
在个人fork仓库页面,点击pull request
-
如果想要将自己的改动推送到原仓库
-
如果是同步原仓库到自己fork的仓库(即同步原仓库)
那么向fork的仓库提交PR即可,merge之后,即保持了原仓库的同步
2021更新:目前Github上fork了项目之后,在自己仓库对应项目下面已经有了Fetch upstream按钮,可以直接方便的进行同步。
-
-
第二种方法,命令行的方式
-
再添加一个远程的源,这个源的url是官方仓库的url
git remote add upstream https://github.com/xxxx原仓库的GitHub的https或者git地址
-
每次修改issue或者有新的功能添加的时候,建议都新开一个分支。
本地新建并切换到issue#4673分支上,并将官方的master分支合并到当前分支git checkout -b issue#4673 upstream/master
# 上面git push也说到过,设置upstream的目的是为了简化其他命令 git branch --set-upstream-to=upstream/master
在这个分支上修改完之后,提交之前,拉取一下,看看有没有冲突
git pull
此时会默认从upstream的远程仓库拉取,因为上面设置了
小提示:如果使用git pull在拉取官方原仓库的时候,有时候会弹出vim编辑器,git 默认会生成一个 merge branch master of…的信息,如果,此后提交PR的时候会发现会带上这种信息,很不美观
解决方案:git pull --rebase=true # 或者 git pull --rebase
或者当vim编辑器被打开时,什么都不写,:wq保存退出,此时就会生成两条并行的线,然后再
git rebase
那么此时就会变成一条直线
本地改动之后commit,然后推送到远程自己fork的仓库,origin是自己fork的远程仓库名字
git push -f origin issue#4673
这时,在GitHub个人fork的仓库页面,即可找到刚才的提交上来的分支,向原仓库提交PR即可.提交步骤参考上面的同步第二步骤
这里为什么是push的时候使用了-f参数呢,强制将本机代码推送到远程。其实在切换到该分支的时候,包括提交之前,我们本地额issue分支已经和官方仓库的master分支保持一致了,所以,push的时候直接让远程的issue和本机代码保持一致。
同时还要注意:如果远程origin的master分支,我们在本地pull 官方原仓库之后,那本地肯定是领先于origin的master分支的,这时候,如果不加-f参数,那么git push 会报错,! [rejected] master -> master (non-fast-forward)
但是,个人建议,平时公司团队开发push的时候尽量不要用-f参数.当PR被官方merge之后,则切换到origin的master分支,进行和原仓库同步
# 如果不指定远程仓库,默认是origin,git checkout upstram/master 是切换到远程仓库upstream的master分支 git checkout master # 拉取远程仓库upstream的master分支,并合并到当前分支 git pull upstream master
此时,本地的代码已经和fork的原仓库代码保持了一致
删除本地刚才修复bug的issue#4673分支
git branch -d issue#4673
删除远程对应的分支
git push origin --delete issue#4673
-
GitHub使用说明
关于GitHub详细使用,比如从最开始的注册账户、到创建仓库、提交PR、合并PR、设置git账号到高级点的在整个GitHub上搜索某个语言的某个仓库、某个仓库stars大于100,基于特定作者、基于最近push的种种搜索,以及GitHub的表情,都可以直接在官方文档找到说明.如下图所示,可以切换语言,一般使用文档参考第一个模块即可
结束
到此为止,完整的流程已经走完
备注
其他一些操作
- 查看本机git 配置
git config --global --list
- 设置git
git config --global user.name "用户名"
git config --global user.email "用户邮箱"
- 生成 ssh key
ssh-keygen -t rsa -C "邮箱"
- 清理Git本地缓存
git remote prune origin
更多推荐
所有评论(0)