Git基本使用以及如何向开源项目提交PR

目标

  1. 非常快速的和fork的源仓库保持同步
  2. 修改代码之后,方便的、快速的提交代码到fork的仓库,并向原仓库提交PR
  3. 掌握在gitee和GitHub之间快速切换
  4. 掌握标准的贡献开源的步骤

Git 基本操作

  1. GitHub上fork一个项目
  2. 克隆到本地
git clone git@github.com:jacksparrow414/hello-world.git
  1. 新建一个名字为develop的分支,checkout -b 新建分支并切换到该分支
git checkout -b develop
  1. 在develop分支修改代码
  2. 提交暂存
git add .

如果提交到暂存区的文件想要移出暂存区怎么处理?

可以使用下面的命令

git reset HEAD 文件名

或者

git rm --cached 文件名
  1. 提交到本地仓库,-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
  1. 推送到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
    

    两种方式效果一样

  • 建议建议平时可以使用第三种方式,更简单

  1. 推送到个人远程分支之后,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
      

      查看本地都有哪些远程的源仓库

  2. 合并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分支
    在这里插入图片描述

  3. 回退HEAD指针到前几步

    • 保留本地提交信息

      # HEAD~N,表示回到N步,N是数字
      git reset --soft HEAD~2
      
    • 不保留本地提交信息

      git reset --hard HEAD~2
      
  4. 如果已经推送到远程了,发现提交的文件有问题,想要撤销这次提交。使用git revert 命令。revert命令会生成一次新的提交历史,来表明这次提交时撤销某一次的提交

     # commitId是想要撤销的某一次提交的commitId
     git revert commitId
     
     git push
    
  5. 如果本地曾经修改过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
那么如何同官方的仓库保持同步呢?
  1. 第一种方法,GitHub个人fork仓库页面,如图

    • 在个人fork仓库页面,点击pull request
      在这里插入图片描述

    • 如果想要将自己的改动推送到原仓库
      在这里插入图片描述

    • 如果是同步原仓库到自己fork的仓库(即同步原仓库)
      在这里插入图片描述
      那么向fork的仓库提交PR即可,merge之后,即保持了原仓库的同步
      2021更新:目前Github上fork了项目之后,在自己仓库对应项目下面已经有了Fetch upstream按钮,可以直接方便的进行同步。

  2. 第二种方法,命令行的方式

    • 再添加一个远程的源,这个源的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的表情,都可以直接在官方文档找到说明.如下图所示,可以切换语言,一般使用文档参考第一个模块即可

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

结束

到此为止,完整的流程已经走完

备注

其他一些操作

  1. 查看本机git 配置
    git config --global --list
    
  2. 设置git
    git config --global user.name "用户名"
    
    git config --global user.email "用户邮箱"
    
  3. 生成 ssh key
    ssh-keygen -t rsa -C "邮箱"
    
  4. 清理Git本地缓存
    git remote prune origin
    
Logo

鸿蒙生态一站式服务平台。

更多推荐