基於Gerrit的Git常用命令
摘要
本文介紹日常開發中常用的git命令,從初階到高階都有,以及相關git、gerrit原理,以提升協同開發效率。
簡介
-
git是一種VCS(version control system)工具,類似於SVN等,由Linux發明人林納斯在兩週內開發出來。
-
gerrit是一種代碼review平臺,處於本地倉庫和遠程倉庫之間的臨時倉庫,部署好gerrit服務器後,本地代碼無法直接push到遠程倉庫,需要先push到gerrit,然後經過review(+1、+2)、merge,才能合入遠程倉庫。基於這種特性,gerrit爲我們提供了很多便利,比如當做自己本地提交的備份,以防本地修改丟失無法找回。
-
提交記錄講解:
一條提交記錄主要包含以下幾個信息:
- Commit Message:該記錄的描述信息。
- Commit Id:該記錄的節點hash,可變。rebase時可能修改。
- Parent Id:該記錄的上一條記錄的Commit Id,可變。rebase時可能修改。
- Change Id:該記錄的唯一標識符,不變。常附於Commit Message末尾,用於在Gerrit上更新提交記錄。但是cherrypick時注意刪除或修改,否則會將該提交之前依賴的所有提交一起同步過去。
- Author:創建該記錄的人,不變。
- Committer:最後一次更新該提交的人,可變。
一、 clone
示例1
git clone “xxxxxxxx”
解讀:
拷貝一個git倉庫到本地。
二、 branch
示例1
git branch -a
D:\demo>git branch -a
master
* temp/feature/demo
remotes/origin/HEAD -> origin/master
remotes/origin/master
解讀:
-a
就是-all的意思,查看本地倉庫的所有分支(包括本地自己創建的分支和遠程服務器的所有分支)。*
表示當前分支。master
爲默認創建的基礎分支。
示例2
git branch -D demo/master
解讀:
刪除本地倉庫中名爲demo/master
的這個分支,執行這個命令之前,需要先切換到別的分支,該操作需謹慎使用。
三、 checkout
示例1
git checkout -t remotes/origin/temp/feature/demo
D:\demo>git checkout -t remotes/origin/temp/feature/demo
Switched to a new branch 'temp/feature/demo'
Branch 'temp/feature/demo' set up to track remote branch 'temp/feature/demo' from 'origin'.
解讀:
基於遠程倉庫的origin
這個根節點下的temp/feature/demo
分支,創建一個同名本地分支,即,本地創建一個名爲temp/feature/demo
的分支,關聯到遠程的origin/temp/feature/demo
分支。
示例2
git checkout origin/master
解讀:
切換到本地倉庫中名爲origin/master
的分支,執行這個命令前,需要先處理當前分支已有的修改,可以通過提交保存、放棄修改來處理。
示例3
git checkout – .
解讀:
放棄當前分支所有修改。
四、 fetch
示例1
git fetch origin
D:\demo>git fetch origin
Fetching origin
remote: Counting objects: 773, done
remote: Finding sources: 100% (586/586)
remote: Total 586 (delta 286), reused 516 (delta 286)
Receiving objects: 100% (586/586), 250.79 KiB | 7.17 MiB/s, done.
Resolving deltas: 100% (286/286), completed with 61 local objects.
From xxxxxxxx
23176be..21cbecc temp/feature/demo -> origin/temp/feature/demo
ff3b558..cf30d71 temp/feature/demo2 -> origin/temp/feature/demo2
解讀:
獲取遠程倉庫下origin
這個根節點下的所有分支信息並同步到本地倉庫,當遠程倉庫新建了分支或更新了提交記錄時,通過這個命令可以同步信息到本地。
示例2
git fetch --all
解讀:
獲取遠程倉庫所有分支信息並同步到本地倉庫。
五、 status
示例1
git status
D:\demo>git status
On branch temp/feature/demo
Your branch is up to date with 'origin/temp/feature/demo'.
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: src/com/zengyu/demo/Demo.java
no changes added to commit (use "git add" and/or "git commit -a")
解讀:
查看當前git狀態,包括分支狀態、文件狀態和操作狀態。
六、 add
示例1
git add src/com/zengyu/demo/Demo.java src/com/zengyu/demo/Demo2.java
解讀:
將本地修改的文件添加到本地暫存區,多個文件之間用空格隔開。
示例2
git add .
解讀:
將本地修改的所有文件添加到本地暫存區。
七、 commit
示例1
git commit -a
解讀:
將本地暫存區所有內容提交生成一條記錄,執行該命令會進入vim界面提示輸入commit message,按Insert
鍵進入編輯模式,如果不熟悉vim命令,請不要使用任何快捷鍵組合,因爲可能觸發vim命令導致不可預料問題,編輯完成後,先按Esc
退出編輯模式,再輸入:wq
保存修改並退出(write and quit)
示例2
git commit -a --amend
解讀:
和示例1不同的是,該命令會把提交記錄合併到上一條提交記錄。用於追加修改或者解衝突後合併修改。
八、 push
示例1
git push origin HEAD:refs/for/temp/feature/demo
解讀:
將本地所有提交記錄都推送到gerrit服務器上origin
根節點下的temp/feature/demo
分支。
九、 pull
示例1
git pull
解讀:
拉取遠程倉庫對應當前分支的提交記錄到本地,可能和本地提交記錄或當前未保存的修改衝突。
示例2
git pull --rebase
解讀:
在示例1的基礎上執行變基操作,假設情景:本地同步到遠程最新,然後本地修改並提交記錄,他人有推送併合入到遠程倉庫,在沒有衝突的情況下,當拉取遠程提交記錄到本地並變基時,會將本地提交記錄節點移動到更新的遠程記錄之後。常用於同步最新代碼。如果無法處理好解衝突操作,請使用後面的cherrypick方式來同步。
十、 rebase
示例1
git rebase
解讀:
單純的變基操作,當你發現本地倉庫git記錄線性圖很奇怪時,可以嘗試。通常在執行git pull
並解決衝突後執行該命令。
示例2
git rebase -i
解讀:
處理本地倉庫當前分支中,所有未同步到遠程分支的提交記錄,執行該命令會進入vim頁面,根據提示可以選擇需要合併的提交。
十一、 cherrypick
示例1
git fetch “xxxxxx” refs/changes/1/12345/222 && git cherry-pick FETCH_HEAD
解讀:
在gerrit上提交記錄中找到cherrypick的命令。該命令可以將某一條提交記錄同步到本地倉庫,注意處理衝突,解決完衝突時執行git cherry-pick --continue
,解不了衝突選擇放棄時執行git cherry-pick --abort
。需要注意的是,cherrypick的提交記錄中可能包含changeId,因此需要對本地的該記錄處理一下提交信息,通過git commit --amend
進入vim頁面刪除或修改changeId,爲何需要修改changeId見簡介。
十二、 stash
示例1
git stash
解讀:
將當前所有修改存入一個changeList,通常用於保存一些無需推送到服務器但是經常修改的內容,比如sdk配置、keystore配置的修改。執行該命令後,本地修改將重置。
示例2
git stash apply
解讀:
將changeList中的頂部修改記錄還原到本地,注意衝突問題。
示例3
git stash list
解讀:
查看changeList中所有記錄,可以通過在示例1基礎上追加記錄編號的方式指定還原的修改記錄git stash apply 1
。
十三、 reset
示例1
git reset --hard
解讀:
重置當前所有修改,慎用。
示例2
git reset --hard origin/temp/feature/demo
解讀:
回退當前分支所有提交記錄,即同步到之前更新的遠程倉庫的分支節點,僅在本地提交的記錄將全部丟失,慎用。如果先執行git fetch origin
,接着執行該命令,再執行git pull
,可將當前分支同步到遠程倉庫最新狀態,在這之前,先處理好本地的修改(放棄or保存在gerrit)
示例3
git reset --hard 00f0587
解讀:
根據提交的hash,指定回退到那筆提交記錄。查詢hash見git log
或者git reflog
。該命令是誤操作的後悔藥。
示例4
git reset --hard HEAD~3
解讀:
指定回退幾個提交記錄。
十四、 log
示例1
git log
解讀:
查看本地倉庫當前分支所有提交記錄,如果記錄太多顯示不全,命令行出現:
的時候按q
退出。
示例2
git log --oneline -5
解讀:
在示例1的基礎上,簡化記錄爲單行顯示,並限制條數。
十五、 reflog
示例1
git reflog
解讀:
查看本地倉庫所有操作記錄,其他操作同十四。
日常開發(針對不熟練的)
- 本地修改後推送到gerrit上備份。
git fetch --all && git reset --hard origin/XXXXXX && git pull
同步代碼到遠程倉庫最新。- cherry-pick剛纔備份的那筆提交到本地,並解衝突。追加commit message時把gerrit上備份記錄的change id附在末尾,這樣就將該提交和gerrit上備份那筆關聯起來了,之後再推送時,就不會生成多的提交記錄。
總結
- 熟能生巧,忌用GUI。
- 不恥下問,勤做筆記。
- 學無止境。
- Enjoy work