由於今年轉向Framework開發了,進來發現公司內部使用的都是Git作爲版本控制,來之前使用的也不多,進來後也使用了將近半年了,都會用了,但命令還是不太容易記住,所以在這裏做一個記錄,畢竟好記性不如爛筆頭。
注:以下內容從博文http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/學習總結而來。在此,感謝原作者。
Git是一個開源的分佈式版本控制系統,可以有效、高速的處理或大或小的項目版本管理。Git起初是由Linus Torvalds開發的。
目前版本控制系統主要有兩種,分別是集中式版本控制系統(如CVS和SVN)和分佈式版本控制系統(如Git)。
集中式版本控制系統:有一箇中央服務器,所有代碼庫都只保存在其中,工作時都用的自己電腦,從服務器獲取,提交時最終都要彙總到中心服務器。總之,服務器掛了,所有庫都完蛋了。而且必須要聯網的情況下才能使用,上傳速度也慢。
分佈式版本控制系統:分佈式版本控制系統沒有中央服務器,每個人的電腦上都是一個完整的版本庫,只要交換對方的修改就行,把各自的修改推送給對方。而且分佈式版本控制系統也有一臺充當“中央服務器”的電腦,只是用來交換修改之用。
區別:集中式需要聯網,分佈式不需要;集中式上傳速度慢,分佈式快;集中式必須要有中心節點才能幹活,分佈式可以不需要;集中式不需要初始化很多東西就能幹活,而分佈式則要拷貝整個歷史記錄。
一、安裝和創建版本庫
1、安裝和配置
三大操作系統平臺都支持,安裝很簡單,然後主要是安裝後的配置。
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
git config命令的–global參數,表示你這臺機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的用戶名和Email地址。
2、創建版本庫
版本庫也即(倉庫)repository,也可理解爲一個目錄。
第一步:Linux下創建目錄:
yjq@ubuntu:~$ mkdir learn_android
yjq@ubuntu:~$ cd learn_android/
yjq@ubuntu:~/learn_android$ pwd
/home/yjq/learn_android
第二步:git init將目錄變成Git可以管理的倉庫:
yjq@ubuntu:~/learn_android$ git init
Initialized empty Git repository in /home/yjq/learn_android/.git/
執行ll命令可看到多了一個.git文件夾
yjq@ubuntu:~/learn_android$ ll
total 12
drwxr-xr-x 3 yjq root 4096 Aug 26 17:06 ./
drwxr-xr-x 10 yjq root 4096 Aug 26 16:57 ../
drwxr-xr-x 7 yjq root 4096 Aug 26 17:06 .git/
第三步:添加文件到Git倉庫裏:
新建文件readme.txt:
yjq@ubuntu:~/learn_android$ touch readme.txt
yjq@ubuntu:~/learn_android$ ls
readme.txt
用git來add和commit文件:
yjq@ubuntu:~/learn_android$ git add readme.txt
yjq@ubuntu:~/learn_android$ git commit -m "add a new file"
[master (root-commit) 133b2fb] add a new file
0 files changed
create mode 100644 readme.txt
二、版本管理
1、版本修改查看
往readme.txt中添加文本blablabllblablalblbal,然後使用git status查看:
yjq@ubuntu:~/learn_android$ git status
yjq@ubuntu:~/learn_android$ git status
# On branch master
# 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: readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
git diff查看文件修改內容:
yjq@ubuntu:~/learn_android$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
old mode 100644
new mode 100755
index e69de29..6741507
--- a/readme.txt
+++ b/readme.txt
@@ -0,0 +1 @@
+blablabllblablalblbal
\ No newline at end of file
然後git add和commit:
yjq@ubuntu:~/learn_android$ git add readme.txt
或使用:
yjq@ubuntu:~/learn_android$ git add .
將當前目錄所有未加入版本的文件add進來。
git status查看:
yjq@ubuntu:~/learn_android$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#
git commit提交:
yjq@ubuntu:~/learn_android$ git commit -m "add some content to readme.txt"
[master 5213fcd] add some content to readme.txt
1 file changed, 1 insertion(+)
mode change 100644 => 100755 readme.txt
2、版本回退
執行git log命令可查看我們從最近到最遠的詳細提交日誌,若是想簡略的顯示,則執行:
git log –pretty==oneline
在Git中使用HEAD表示當前版本,HEAD^ 表示上一個版本,HEAD^^ 表示上上個版本。
回退到上一個版本:git reset –hard HEAD^
回退到版本100644:git reset –hard 100644
回退到某個版本後,若是又想恢復到新版本,先執行:git reflog找到歷史命令中自己想要恢復的版本的commit id,然後執行:git reset –hard commit_id
3、工作區和暫存區
Git和其它版本控制系統如SVN的一個不同是擁有暫存區的概念。
工作區(Working Directory):就是在電腦中能看到的目錄,比如前面的learn_android目錄。
版本庫(Repository):即工作區中的隱藏目錄“.git”。
Git的版本庫裏存了最重要的稱爲stage(或者叫index)的暫存區,還有Git爲我們自動創建的第一個分支master,以及指向master的一個指針HEAD。
暫存區就是存放修改後的待提交文件,git add命令就是將要提交的所有修改放到暫存區(Stage),而git commit命令就是將暫存區的所有修改提交到分支。
4、管理修改
git diff HEAD – readme.txt 可以查看工作區和版本庫裏面最新版本的修改信息。當我們每次修改文件後,若是不把修改內容add進暫存區,那也就無法加入到commit中。
5、撤銷修改
git checkout – file 可以丟棄工作區的修改,有可能回到最近一次的git commit狀態或是git add時的狀態。
note:git checkout file表示創建一個file新分支。
用命令 git reset HEAD file 可以把暫存區的修改撤銷掉(unstage),重
新放回工作區。
git reset 命令既可以回退版本,也可以把暫存區的修改回退到工作區。當我們用HEAD時,
表示最新的版本。
6、刪除文件
本地刪除命令 rm test.txt ,然後版本庫中刪除命令 git rm test.txt ,若是刪除後想恢復 git checkout – test.txt
三、遠程倉庫
Git是分佈式版本控制系統,同一個Git倉庫,可以分佈到不同的機器上。這裏需要有一個原始的版本庫,就一現成的Github託管爲例,註冊賬號後,由於本地Git倉庫和Git遠程倉庫之間的傳輸是通過SSH加密的,所以,設置:
第一步,創建SSH Key,Shell下或Git bash下執行:$ ssh-keygen -t rsa -C “郵件地址”,一路設置,最終可在用戶主目錄裏面生成.ssh目錄,裏面包含有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的祕鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,可
以放心地告訴任何人。
第二步,登陸GitHub,打開“Account settings”,“SSH Keys”頁面,然後點擊“Add SSH Key”,填上任意Title,在Key文本框裏面黏貼id_rsa.pub文件的內容,然後點擊“Add Key”,就可以看到添加成功的Key了。
GitHub允許添加多個Key,以便可以在多臺電腦上進行提交。
1、添加遠程庫
在本地已經創建過一個Git倉庫後,我們再在GitHub上創建一個Git倉庫,以便進行遠程同步。
首先,在GitHub上找到“Create a new repo”按鈕,然後創建一個新的Git倉庫,在Repository name裏面填入learn_android,其他保持默認,點擊“Create repository”就可成功創建一個新的Git倉庫。
由於GitHub上的learn_android倉庫是空的,所以我們將本地倉庫與之關聯,在本地的learn_android倉庫下執行:
$ git remote add origin [email protected]:GitHub賬號名/learn_android.git
origin就是遠程倉庫的名字,也可以改成別的名字。下一步,再將內容推送遠程庫,執行:
$ git push -u origin master
就是將當前分支master推送到遠程。第一次推送加了-u參數,不僅是爲了將本地的master分支推送到遠程新的master分支,還可以將本地的master分支和遠程的master分支關聯起來,以便在以後的推送和拉取中簡化命令。
之後只要做了修改,只需執行:
$ git push origin master
就可把本地master分支的最新修改推送至GitHub服務端。
2、從遠程庫克隆
用命令git clone克隆一個本地庫:
SSH方式:$ git clone [email protected]:GitHub賬號名/倉庫名.git
Https方式:**https://github.com/
GitHub賬號名/倉庫名.git**
Git支持多種協議,包括https,但通過ssh支持的原生git協議速度最快
四、分支管理
1、創建分支與合併分支
創建dev分支,然後切換到dev分支:
$ git checkout -b dev
Switched to a new branch 'dev'
相當於一下兩步:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
git branch查看分支:
$ git branch
* dev
master
開發過程,現在dev分支開發,完成後,切回到master分支:
$ git checkout master
Switched to branch 'master'
然後合併dev分支到master分支:
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
Fast-forward表示“快進模式”,所以非常快。合併完成後,刪除dev分支:
$ git branch -d dev
Deleted branch dev (was fec145a).
再次查看:
$ git branch
* master
2、解決衝突
噹噹Git無法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併。用 git log –graph 命令可以看到分支合併圖,如:
$ git log --graph --pretty=oneline --abbrev-commit
3、分支管理策略
通常,合併分支時,如果可能,Git會用“Fast forward”模式,但這種模式下,刪除分支
後,會丟掉分支信息,所以若是想要保留合併的歷史,在merge時加上–no-ff參數就會使用普通模式進行合併,而且合併後在版本庫中會有記錄。如:
git merge --no-ff -m "merge with no-ff" dev
4、Bug分支
若是在某個開發分支工作進行到一半,需要修復一個已有版本的bug,那麼先將工作現場儲藏起來,執行:
$ git stash
Saved working directory and index state WIP on dev: 6224937 add
merge
HEAD is now at 6224937 add merge
假設需要在master分支進行修改,則創建臨時分支,執行:
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
$ git checkout -b issue-101
Switched to a new branch 'issue-101'
修改完成後再合併,然後刪除臨時分支,最後再切回之前的開發分支。
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 2 commits.
$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
readme.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git branch -d issue-101
Deleted branch issue-101 (was cc17032).
$ git checkout dev
Switched to branch 'dev'
$ git status
# On branch dev
nothing to commit (working directory clean)
回到dev分支後,執行git stash list命令,查看stash的內容:
$ git stash list
stash@{0}: WIP on dev: 6224937 add merge
然後,恢復之前保存的內容,並將stash的內容刪除,執行:
$ git stash pop
# On branch dev
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: hello.py
#
# 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: readme.txt
#
Dropped refs/stash@{0} (f624f8e5f082f2df2bed8a4e09c12fd2943bdd40)
或者分別執行:git stash apply恢復和git stash drop來刪除。
5、Feature分支
開發一個新feature時,最好新建一個分支,若是要丟棄一個沒有被合併過的分支,執行強制刪除命令:* git branch -D 分支名稱*
6、多人協作
查看遠程庫的信息命令:git remote:
$ git remote
或者用git remote -v顯示更詳細的信息:
$ git remote -v
推送本地master分支到遠程倉庫:
$ git push origin master
推送本地dev分支到遠程倉庫:
$ git push origin dev
假設要在dev分支上開發,那麼創建遠程倉庫origin的dev分支到本地:
$ git checkout -b dev origin/dev
git push origin dev若是失敗,就先用git pull從origin/dev拉取更新,本地合併解決衝突後再推送,若git pull也失敗,出現“no tracking information”提示,原因可能是沒有指定本地dev分支與遠程origin/dev分支的鏈接,那麼,我們設置鏈接:
$ git branch --set-upstream dev origin/dev
Branch dev set up to track remote branch dev from origin.
然後在git pull。
首先,可以試圖用 git push origin branch-name 推送自己的修改;
如果推送失敗,則因爲遠程分支比你的本地更新,需要先用 git pull試圖合併;
如果合併有衝突,則解決衝突,並在本地提交;
沒有衝突或者解決掉衝突後,再用git push origin branch-name 推送就能成功。
五、標籤管理
1、創建標籤
首先,切換到打標籤的分支:
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
然後,用命令 git tag name打標籤:
$ git tag v1.0
用命令 git tag 查看所有標籤:
$ git tag
v1.0
在commit id是“6224937”的版本上打標籤:
$ git tag v0.9 6224937
注:標籤不是按時間順序列出,而是按字母排序的。
用 git show tagname 查看標籤信息:
$ git show v0.9
創建帶有說明的標籤,用-a指定標籤名,-m指定說明文字:
$ git tag -a v0.1 -m "version 0.1 released" 3628164
通過-s用私鑰簽名(簽名採用PGP簽名的):
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a
一個標籤:
2、操作標籤
標籤打錯了,進行刪除:
$ git tag -d v0.1
Deleted tag 'v0.1' (was e078af9)
如果要推送某個標籤到遠程,使用命令 git push origin tagname :
$ git push origin v1.0
或者,一次性推送全部尚未推送到遠程的本地標籤:
$ git push origin --tags
如果標籤已經推送到遠程,先從本地刪除:
$ git tag -d v0.9
然後,從遠程刪除。刪除命令也是push,但是格式如下:
$ git push origin :refs/tags/v0.9
六、自定義Git
讓Git顯⽰示顏色
$ git config --global color.ui true
忽略特殊文件,GitHub已經幫忙配置好了https://github.com/github/gitignore
配置別名,如配置git status的別名爲st:
$ git config --global alias.st status
配置reset HEAD的別名爲unstage:
$ git config --global alias.unstage 'reset HEAD'
配置一個 git last ,讓其顯示最後一次提交信息:
$ git config --global alias.last 'log -1'
配置有顏色格式等信息的log:
$ git config --global alias.lg "log --color --graph --
pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)
%C(bold blue)<%an>%Creset' --abbrev-commit"