Git Bash 提交代碼的正確姿式

項目經驗,如需轉載,請註明做者:Yuloran (t.cn/EGU6c76)git

前言

本文介紹如何使用 Git Bash 命令行,提交代碼、解決衝突,以及如何避免衝突。有助於理解 Android Studio 的 VCS 背後的原理。github

檢出代碼

檢出遠程倉庫

git clone https://github.com/Yuloran/GitTutorial.git
複製代碼

能夠檢出 origin/master 分支到本地,這是 GitHub 建立倉庫時默認的 主機名/分支名。使用 git branch -vv 查看本地分支狀態:vim

可見,本地分支名爲 master,關聯的遠程分支名爲 origin/master(origin 是主機名,master 是分支名)。bash

檢出遠程分支

不少時候,配置管理員須要新建不少遠程分支,以進行同一項目不一樣版本的並行開發。好比,有的分支用於需求開發,有的分支用於 Bug 修復等。此時,咱們須要檢出各自對應的分支,修改並提交代碼。編輯器

同步遠程分支

管理員新建遠程分支後,咱們須要先同步一下遠程分支,才能看到新建的分支:fetch

如上圖所示,先使用 git branch -a 查看本地和遠程全部分支,發現並無管理員新建的 bug_fix 分支,此時輸入 git fetch,提示有一個新分支 bug_fix。再次輸入 git branch -a 查看全部分支:ui

嗯,確實多了一個 bug_fix 分支。spa

檢出遠程分支

git checkout -b bug_fix -t remotes/origin/bug_fix
複製代碼

checkout -b 表示新建本地分支,bug_fix 爲本地分支名,你也能夠起別的名字。-t 表示追蹤遠程分支(track),remotes/origin/bug_fix 爲遠程分支名,查看檢出結果:命令行

輸入 git branch 查看當前所在的本地分支:3d

輸入 git status 查看當前分支狀態:

提示你目前修改是最新的,沒有任何修改能夠提交。

提交代碼

不良習慣

不少開發人員,喜歡在一個本地分支上,連續提交代碼。這是一個很很差的習慣,尤爲是在多人協做的狀況下。這會致使每筆提交之間存在依賴關係,即便每筆修改之間毫無瓜葛。進而可能致使 merge 衝突、cherry-pick 合入冗餘代碼。並且,若是你忽然發現,上上一筆提交有問題的時候,我以爲你可能有種想 shi 的感受。

正確姿式

保留一個本地分支,專門用於同步代碼。

好比,咱們如今須要在 master 分支上作一個需求,首先輸入 git status 查看本地 master 分支的狀態:

提示本地有修改文件,沒有提交。咋整呢?有兩種處理方法:

  • 啥也無論,直接輸入 git pull 進行同步,有衝突會自動合併,合併不了再手動解決。-> 不推薦,可能會在本地產生一條 merge 記錄
  • 先將本地修改 stash save,再使用 git pull --rebase 進行同步,最後將暫存的修改 stash pop,有衝突會自動合併,合併不了再手動解決。-> 推薦,自動變基,不會在本地產生 merge 記錄

1. 暫存代碼

git stash save [-u] 'update readme.md'
複製代碼

[-u] 表示參數可選,加 -u 會將本地新增文件也暫存,不加則僅暫存本地修改部分。'update readme.md' 爲描述,下面列出 git stash 支持的全部操做:

  • git stash list 顯示全部暫存記錄
  • git stash show stash@{0} 查看指定的暫存記錄
  • git stash pop stash@{0} 彈出指定的暫存記錄
  • git stash drop stash@{0} 刪除指定的暫存記錄
  • git stash clear 清空暫存記錄

2. 同步代碼

git pull --rebase
複製代碼

同步結果:

提示已是最新的。若是本地代碼不是最新的,應當相似於下圖:

3. 彈出暫存代碼

git stash pop [stash@{0}]
複製代碼

[stash@{0}] 表示可選,不加默認彈出棧頂元素,也能夠指定彈出哪個暫存記錄。彈出結果以下:

提示有衝突。莫要驚慌,有衝突解決就是了,畢竟我們乾的都是「小項目」,除非文件換行符變了,不然不會衝突太多。像 AOSPMokee 那種大型項目,發生衝突纔是坑爹。好比國內的手機廠商,每次大版本升級時(好比從 Android 8.0 升到 Android 9.0),都須要花幾個月的時間才能使版本穩定,這也是爲何國產手機安卓版本老是落後於 Google 的緣由。扯遠了,仍是先 git status 看一下工做區狀態:

原來是 README.md 文件修改衝突了,並且 Git 還貼心地提示你:

  • 使用 git reset HEAD <file> 來丟棄本地修改
  • 使用 git add <file>... 標記衝突解決(省略號表示後面可接多個文件,以空格分隔)

咱們先使用 git diff <file> 看看哪裏衝突了:

git 使用:

<<<<<<< Updated upstream

=======
>>>>>>> Stashed changes
複製代碼

標記衝突狀態,======= 上面的是遠程倉庫上別人的修改,下面的是咱們的本地修改。嗯,這個衝突是我人爲製做的,因此比較簡單。在 IDE 中手動解決該衝突後,使用 git add README.md 命令標記衝突已解決:

README.md 咋變原諒色了呢?由於咱們剛纔用了 git add 命令,將其添加到了暫存區,因此上面顯示的是 Changes to be committed,也就是待提交。提交啥啊,剛解決完衝突,需求還沒作呢!因此,咱們使用 git reset <file>... 命令,將其從暫存區撤出:

image.png

<file>... 表示可選,不加即撤出全部,加了即撤出指定的文件。Linux 幫助手冊中不少使用 <arg> 或者 [arg] 表示參數可選,<>[] 是不須要輸入的,這個已經成爲開發人員的習慣用法。

4. 新建本地分支

不少人這個時候,就直接在本地 master 分支上瘋狂輸出需求代碼了。NO!咱們應該針對不一樣的開發內容,新建不一樣的本地分支。好比 feature_shoppingbugfix_tombstone 等等,假設咱們如今須要實現一個購物功能,咱們應該使用 git checkout -b feature_shopping 新建一個本地分支來實現這個需求:

5. 提交代碼

連續通宵5天后,咱們的需求終於作完了,能夠提交代碼了:

git commit -m "update README.md" 表示將修改提交到本地倉庫,此時尚未推送到遠程倉庫。-m 後面的是修改描述,這是一種簡便寫法。而大公司都會對提交的描述有格式要求,因此須要先配置 commit 模板:

git config --global commit.template ~/.gitmsg
複製代碼

編輯該模板:

輸入 git commit

模板已經生效了,輸入修改描述便可。我這裏配置的 Git 編輯器是 vim,你也能夠配置成別的:

git config --global core.editor notepad
複製代碼

這樣,就能夠用記事原本編寫修改描述了。

6. 追加提交

commit 以後,本地又修改了一些文件,此時須要使用 git commit --amend 追加提交:

7. 回退提交

commit 以後,發現提交多了,把不須要提交的也提交了,此時須要回退,有兩種方式:

  • git reset [--soft] commit_id,軟回退,不會丟棄文件修改記錄,--soft 不加也能夠。
  • git reset --hard commit_id,硬回退,丟棄全部修改。通常僅在須要回退到指定節點驗證問題時使用。

查看 commit_id:

git log -1
複製代碼

-1 表示只查看提交記錄裏的最後一條:

輸入 git reset 306c8b26360adfbdb3992f62514e8d58626f2d20,便可回退提交。而後從新 git add <file>...git commit

8. 推送代碼

commit 以後不少人就直接 git push 了,這是不對的,應當先同步代碼。因爲咱們如今在新建的本地分支 feature_shopping 上,這個分支沒有關聯遠程分支,因此沒法也不該該使用 git pull --rebase 來同步代碼。正確的操做爲:

  1. git checkout master:切到本地主分支
  2. git pull --rebase:同步代碼
  3. git checkout feature_shopping:切換到本地需求分支
  4. git rebase master:將本地主分支代碼,合入到本地需求分支(可能有衝突,按照 Git 的提示修復便可)
  5. git push origin HEAD:refs/for/master:將本地需求分支的提交推送到遠程 master 分支

結語

Git Bash 每個命令的操做結果,成功或者出錯的描述都很詳細。遇到問題的時候,只要按照提示,一步步操做,通常都能解決。

相關文章
相關標籤/搜索