Git基本使用以及如何向開源項目提交PR(常見問題整理-超實用)

Git基本使用以及如何向開源項目提交PR

目標

  1. 非常快速的和fork的源倉庫保持同步
  2. 修改代碼之後,方便的、快速的提交代碼到fork的倉庫,並向原倉庫提交PR
  3. 掌握在gitee和GitHub之間快速切換
  4. 掌握標準的貢獻開源的步驟

Git 基本操作

  1. GitHub上fork一個項目
  2. 克隆到本地
git clone [email protected]: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'
# 將忘記提交的文件,例如:忘記提交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
    
  3. 回退HEAD指針到前幾步

    • 保留本地提交信息

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

      git reset --hard HEAD~2
      

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

那麼如何同官方的倉庫保持同步呢?

  1. 第一種方法,GitHub個人fork倉庫頁面,如圖

    • 在個人fork倉庫頁面,點擊pull request
      在這裏插入圖片描述

    • 如果想要將自己的改動推送到原倉庫
      在這裏插入圖片描述

    • 如果是同步原倉庫到自己fork的倉庫(即同步原倉庫)
      在這裏插入圖片描述
      那麼向fork的倉庫提交PR即可,merge之後,即保持了原倉庫的同步

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

    • 再添加一個遠程的源,這個源的url是官方倉庫的url

      git remote add upstream https://github.com/xxxx原倉庫的GitHub地址
      
    • 每次修改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
      

結束

到此爲止,完整的流程已經走完

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章