首頁 > 軟體

Git及常用命令說明

2020-06-16 17:26:22

概述

Git Home: https://git-scm.com/
Git is a version control ststem.  
Git is a free software distributed under the GPL.
Git has a mutable index called stage.
The way that git work:
    Git tracks changes of files.
    work file ---[git add]---> stage(index) ---[commit]---> HEAD-master
    * git add命令實際上就是把要提交的所有修改放到暫存區(Stage),
    * 然後執行git commit就可以一次性把暫存區的所有修改提交到分支。
      * 每次修改,如果不add到暫存區,那就不會加入到commit中。
Git creating a new branch is quick and simple.

修改git使用者名稱稱和郵箱

$ git config --global user.name "Your Name"
$ git config --global user.email email@example.com

初始化git倉庫

初始化一個Git倉庫,使用git init命令。

新增檔案到git倉庫

新增檔案到Git倉庫,分兩步:
第一步,使用命令git add <file>,注意,可反復多次使用,新增多個檔案;
第二步,使用命令git commit,完成。

檢視git倉庫當前狀態

$git status 

如果git status告訴你有檔案被修改過,用git diff可以檢視修改內容

$git diff
$git diff HEAD -- readme.txt
$git diff HEAD^ -- readme.txt 

顯示從最近到最遠的提交紀錄檔

$ git log
$ git log --pretty=oneline
$ git log --graph --pretty=oneline --abbrev-commit (檢視分支合併圖)

回退到以前的版本

$ git reset --hard HEAD^     #回退到上一個版本(只能回到以前的版本)
$ git reset --hard HEAD~100  #回退到上100個版本(只能回到以前的版本)
$ git reset --hard c126a6bd08346e59b95a9cfb5dbea53d6ba2f2a4 #回到特定版本號ID的版本(可以回到以前的版本,也可以回到將來的版本,版本號沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能只寫前一兩位,因為Git可能會找到多個版本號,就無法確定是哪一個了)
$ git reset HEAD readme.txt  #把暫存區的修改回退到工作區(unstage), 用git status可以看到快取區是乾淨的。(這條命令和git checkout -- readme.txt 是相對應的,git checkout -- readme.txt 是將工作區的修改丟棄掉,而git reset HEAD readme.txt 是將快取區的修改回退到工作區)
[] --hard:徹底將版本庫、暫存區、工作區的檔案恢復到指定的版本庫
     --mixed:將版本庫、工作區的檔案恢復到指定的版本庫
     --soft:僅僅將已提交的版本庫恢復到指定的版本庫,一般不用

在Git中,總是有後悔藥可以吃的,Git提供了一個命令git reflog用來記錄你的每一次命令

$ git reflog

讓檔案回到最近一次git commit或git add時的狀態

$git checkout -- readme.txt (注意:這裡沒有--,就變成了“切換到另一個分支”的命令)
把readme.txt檔案在工作區的修改全部復原,這裡有兩種情況:
一種是readme.txt自修改後還沒有被放到暫存區,復原修改就回到和版本庫一模一樣的狀態;
一種是readme.txt已經新增到暫存區,又作了修改,復原修改就回到新增到暫存區後的狀態。
總之,就是讓這個檔案回到最近一次git commit或git add時的狀態。
git checkout其實是用版本庫裡的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。

刪除檔案

一般情況下,你通常直接在檔案管理器中把沒用的檔案刪了,或者用rm命令刪了:
$ rm test.txt

這個時候,Git知道你刪除了檔案,因此,工作區和版本庫就不一致了,git status命令會立刻告訴你哪些檔案被刪除了:
$ git status

現在你有兩個選擇,一是確實要從版本庫中刪除該檔案,那就用命令git rm刪掉,並且git commit:
$ git rm test.txt
$ git commit -m "remove test.txt"

另一種情況是刪錯了,因為版本庫裡還有呢,所以可以很輕鬆地把誤刪的檔案恢復到最新版本
$ git checkout -- test.txt

僅刪除暫存區的檔案

$ git rm --cache <file_name>

分散式工作:新增github遠端倉庫

1. 在本地開發庫生成公鑰和私鑰, 注意秘鑰對的名字不要私自修改,預設為id_rsa*
$ ssh-keygen -t rsa -C "youremail@example.com"

2. 登陸GitHub,開啟“Account settings”,Add SSH Key
   並在本地庫機器測試是否公鑰是否設定成功:ssh -vT git@github.com (偵錯模式下並禁止虛假使用者)

3. 登入Github之後,建立在github建立遠端倉庫,Create a new repo

4. 將本地庫的程式碼推播到遠端倉庫
   4.1. 關聯遠端庫
   $ git remote add origin git@github.com:kinglyjn/test.git         (git協定)
     或 git remote add origin https://github.com/kinglyjn/test.git (https協定)   

   4.2. 第一次推播master分支的所有內容
   $ git push -u origin master

   4.3. 此後,每次本地提交後,只要有必要,就可以使用命令git push origin master推播最新修改
   $ git push origin master

   分散式版本系統的最大好處之一是在本地工作完全不需要考慮遠端庫的存在,也就是有沒有聯網都可以正常工作,
   而SVN在沒有聯網的時候是拒絕幹活的!當有網路的時候,再把本地提交推播一下就完成了同步,真是太方便了!

從遠端倉庫克隆

1. 在本地開發庫生成公鑰和私鑰
    $ ssh-keygen -t rsa -C "youremail@example.com"

2. 登陸GitHub,開啟“Account settings”,Add SSH Key

3. 將遠端程式碼庫克隆到本地,在本地執行瑞安命令
   $ git clone git@github.com:kinglyjn/test2.git
   如果有多個人共同作業開發,那麼每個人各自從遠端克隆一份就可以了

建立分支方式工作

檢視分支:git branch
建立分支:git branch <branch_name>
切換分支:git checkout <branch_name>
建立和切換分支一步完成:git checkout -b <branch_name> 
合併某分支到當前分支:git merge <branch_name>  (快進模式合併分支,當Git無法自動合併分支時,就必須先解決衝突,解決衝突後再提交合併完成。)
刪除分支:git branch -d <branch_name>
強行刪除分支:git branch -D <branch_name> (如果要丟棄一個沒有被合併過的分支就要用到這條命令)

分支管理策略

a. master分支是非常穩定的,僅用來發布新版本,平時不能在上面幹活;
b. dev分支是不穩定的,幹活都在dev分支上,到某個時候,比如1.0版本發布時,再把dev分支合併到master上,在master分支發布1.0版本;
c. 你和你的小夥伴們每個人都在dev分支上幹活,每個人都有自己的分支,時不時地往dev分支上合併就可以了;
d. 開發一個新功能,最好在dev分支上再新建一個feature-id分支;
e. 解決程式bug,最好在相應的分支上新建一個issue-id分支;
f. 快進模式分支:通常合併分支時,如果可能,Git會用Fast forward模式,但這種模式下,刪除分支後,會丟掉分支資訊。
   $ git merge <branch_name>
g. 普通模式分支:合併分支時,加上--no-ff引數就可以用普通模式合併,合併後的歷史有分支,能看出來曾經做過合併。
   $ git merge --no-ff -m "message..." <branch_name>  (因為本次合併要建立一個新的commit,所以加上-m引數,把commit描述寫進去)
h. master時刻與遠端同步;dev是所有成員都在上面工作,需要與遠端同步;feature是否推播取決於你是否和小夥伴合作開發;bug分支沒必要推播到遠端

BUG分支管理

a. 修復bug時,我們會通過建立新的bug分支(eg.issue-101)進行修復,然後合併,最後刪除;
b. 當手頭工作沒有完成時,先把工作現場 git stash 一下,然後去修復bug,修復後,再在相應的分支上git stash pop,回到工作現場。
   $ git stash (儲存工作現場)
   $ git stash list (檢視現有的工作現場列表)
   $ git stash pop <stash@{0}>(恢復並刪除工作現場)
   $ git stash apply <stash@{0}> (恢復而不刪除工作現場) 

多人共同作業

a. 首先,可以試圖 git push origin <branch_name> 推播自己的修改;
   $ git push origin <branch_name>
b. 如果推播失敗,則因為遠端分支比你的本地庫更新,需要先用 git pull 抓取遠端的最新提交,
   抓取遠端的最新提交之後,初始時,你只能看到原生的master分支,如果需要在dev分支上開發,就必須建立遠端庫origin的dev分支到本地
   $ git pull origin <branch_name eg.dev>
   $ git branch --set-upstream dev origin/dev (指定本地dev分支與遠端origin/dev分支連結,下次直接git pull就可以,相當於git pull origin dev)
   $ git checkout -b dev origin/dev (相當於git branch dev origin/dev; git checkout dev)
c. 合併遠端的最新提交,如果合併有衝突,則解決衝突,並在本地提交,沒有衝突後,再用git push origin <branch_name> 推播就能推播成功.
[注] 檢視遠端庫資訊,使用git remote -v;
     本地新建的分支如果不推播到遠端,對其他人就是不可見的;
     git clone 是本地沒有repository時,把整個git專案拷貝下來,包括裡面的紀錄檔資訊,git專案裡的分支,你也可以直接切換、使用裡面的分支等等;
     git pull相當於git fetch和git merge,是本地有repository時,先從遠端下載git專案裡的檔案,然後將檔案與原生的分支進行merge。 

Git標籤

發布一個版本時,我們通常先在版本庫中打一個標籤(tag),這樣,就唯一確定了打標籤時刻的版本。將來無論什麼時候,取某個標籤的版本,就是把那個打標籤的時刻的歷史版本取出來。所以,標籤也是版本庫的一個快照。
Git的標籤雖然是版本庫的快照,但其實它就是指向某個commit的指標(跟分支很像對不對?但是分支可以移動,標籤不能移動),所以,建立和刪除標籤都是瞬間完成的。
a. 建立標籤:git tag <tag_name> (為當前提交HEAD建立標籤)
             git tag <tag_name> 6224937 (為commit id為6224937的版本建立標籤)
             git tag -a <tag_name> -m "message..." (建立標籤並指定標籤資訊)
             git tag -s <tag_name> -m "message..." (建立PGP簽名標籤)
b. 刪除標籤:git tag -d <tag_name> 
c. 檢視標籤:git tag [--list] (檢視標籤列表,按字母順序排序)
             git show <tag_name> (檢視標籤詳細資訊)

Git設定

組態檔的位置:
repository config:在當前倉庫的.git/config
system config:在git安裝目錄下
global config:在電腦當前使用者主目錄下.gitconfig

設定生效順序:
repository config > system config > global config

忽略特殊檔案:
a. 在Git工作區的根目錄下建立一個特殊的.gitignore檔案,然後把要忽略的檔名填進去,Git就會自動忽略這些檔案
b. 不需要從頭寫.gitignore檔案,GitHub已經為我們準備了各種組態檔,只需要組合一下就可以使用了
c. 所有組態檔可以直接線上瀏覽:https://github.com/github/gitignore
d. 忽略的原則:忽略系統自動生成檔案、中間編譯或可執行檔案(eg.*.class)、敏感資訊檔案(eg.密碼口令)
e. 有些時候,你想新增一個檔案到Git,但發現新增不了,原因是這個檔案被.gitignore忽略了,如果你確實想新增該檔案,可以用-f強制新增到Git:
   $ git add -f App.class
   $ git check-ignore -v App.class (找出到底哪個規則忽略了不該忽略的App.class檔案,該命令用於檢查出錯的忽略檔案)

常見引數設定:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
$ git config --global color.ui true (讓git的命令輸出顯示顏色)

設定命令列別名:
$ git config --global alias.st status (告訴Git,以後st就表示status,即git status == git st)
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
$ git config --global alias.unstage 'reset HEAD'
$ git config --global alias.last 'log -1' (git log -1 檢視最近一次的提交)
$ 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"

搭建內部Git伺服器

a. 搭建內部git伺服器非常簡單,通常只需要一下幾步即可(強烈推薦用Ubuntu或Debian,這樣,通過幾條簡單的apt命令就可以完成安裝):
   1. 安裝git
      $ sudo apt-get install git
   2. 建立git使用者來執行git服務
      $ sudo adduser git
   3. 建立證書登入
      收集所有需要登入的使用者的公鑰,就是他們自己的id_rsa.pub檔案,把所有公鑰匯入到/home/git/.ssh/authorized_keys檔案裡,一行一個
      $ cat id_rsa.pub >> ~/.ssh/authorized_keys
   4. 初始化git倉庫(假定是在~/gitrepors資料夾中建立sample.git裸倉庫),然後把owner改為git
      建立裸倉庫,裸倉庫沒有工作區,因為伺服器上的Git倉庫純粹是為了共用,所以不讓使用者直接登入到伺服器上去改工作區,
      並且伺服器上的Git倉庫通常都以.git結尾
      $ sudo chown -R git:git sample.git
   5. 禁用shell登入
      出於安全考慮,第二步建立的git使用者不允許登入shell,這可以通過編輯/etc/passwd檔案完成
      找到類似下面的一行:
      git:x:1001:1001:,,,:/home/git:/bin/bash
      更改為:
      git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
      這樣,git使用者可以正常通過ssh使用git,但無法登入shell,因為我們為git使用者指定的git-shell每次一登入就自動退出   
   6. 克隆遠端倉庫
      $ git clone git@172.16.127.128:~/gitrepors/sample.git
      剩下的推播就簡單了
b. 如果團隊很小,把每個人的公鑰收集起來放到伺服器的~/.ssh/authorized_keys檔案裡就是可行的;
   如果團隊有幾百號人,就沒法這麼玩了,這時,可以用Gitosis來管理公鑰。
c. 要像SVN那樣變態地控制許可權,用Gitolite。

Git 教學系列文章: 

GitHub 使用教學圖文詳解  http://www.linuxidc.com/Linux/2014-09/106230.htm 

Git使用圖文詳細教學  http://www.linuxidc.com/Linux/2016-11/136781.htm

Ubuntu Git安裝與使用 http://www.linuxidc.com/Linux/2016-11/136769.htm

Git 標籤管理詳解 http://www.linuxidc.com/Linux/2014-09/106231.htm 

Git 分支管理詳解 http://www.linuxidc.com/Linux/2014-09/106232.htm 

Git 遠端倉庫???解 http://www.linuxidc.com/Linux/2014-09/106233.htm 

Git 本地倉庫(Repository)詳解 http://www.linuxidc.com/Linux/2014-09/106234.htm 

Git 伺服器搭建與用戶端安裝  http://www.linuxidc.com/Linux/2014-05/101830.htm 

Git 概述 http://www.linuxidc.com/Linux/2014-05/101829.htm 

分享實用的GitHub 使用教學 http://www.linuxidc.com/Linux/2014-04/100556.htm 

Git從入門到學會 http://www.linuxidc.com/Linux/2016-10/135872.htm

Git基本操作詳解 http://www.linuxidc.com/Linux/2016-10/135691.htm


IT145.com E-mail:sddin#qq.com