史上最簡單的git教程

參考:https://www.liaoxuefeng.com/wiki/896043488029600

一、git的簡介

1991年,Linus創建了開源的Linux;
2005年,Linus花了兩週時間自己用C寫了一個分佈式版本控制系統,這就是Git!
2008年,GitHub網站上線了,它爲開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。

Git是分佈式版本控制系統(CVS及SVN都是集中式)

集中式:版本庫是集中存放在中央服務器的,而幹活的時候,用的都是自己的電腦,所以要先從中央服務器取得最新的版本,然後開始幹活,幹完活了,再把自己的活推送給中央服務器。中央服務器就好比是一個圖書館,你要改一本書,必須先從圖書館借出來,然後回到家自己改,改完了,再放回圖書館。
在這裏插入圖片描述
分佈式:版本控制系統根本沒有“中央服務器”,每個人的電腦上都是一個完整的版本庫,這樣,你工作的時候,就不需要聯網了,因爲版本庫就在你自己的電腦上。既然每個人電腦上都有一個完整的版本庫,那多個人如何協作呢?比方說你在自己電腦上改了文件A,你的同事也在他的電腦上改了文件A,這時,你們倆之間只需把各自的修改推送給對方,就可以互相看到對方的修改了

優點:和集中式版本控制系統相比,分佈式版本控制系統的安全性要高很多,因爲每個人電腦裏都有完整的版本庫,某一個人的電腦壞掉了不要緊,隨便從其他人那裏複製一個就可以了。而集中式版本控制系統的中央服務器要是出了問題,所有人都沒法幹活了。

在實際使用分佈式版本控制系統的時候,其實很少在兩人之間的電腦上推送版本庫的修改,因爲可能你們倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。因此,分佈式版本控制系統通常也有一臺充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣幹活,只是交換修改不方便而已。
在這裏插入圖片描述

二、Linux系統安裝git

首先,你可以試着輸入git,看看系統有沒有安裝Git:

$ git

出現下面情況,表示已經安裝,

usage: git [--version] [--help] [-C <path>] [-c name=value]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Use binary search to find the commit that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout   Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Forward-port local commits to the updated upstream head
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.

若出現下面情況:表示未安裝

$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

在Linux上安裝git的方法(Mac OS X與Windows安裝方法點這):

sudo apt-get install git

安裝完成後,還需要最後一步設置(因爲Git是分佈式版本控制系統,所以,每個機器都必須自報家門:你的名字和Email地址。),在命令行輸入:

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

注意git config命令的--global參數,用了這個參數,表示你這臺機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的用戶名和Email地址。

三、git的常用使用技巧

3.1、git創建版本庫命令(repository)

定義:版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄裏面的所有文件都可以被Git管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。

首先,創建一個空目錄(test):

$ mkdir test
$ cd test
$ pwd
/home/my/docker_storage/test

因此,在我的Linux上,這個倉庫位於/home/my/docker_storage/test

第二步,通過git init命令把這個目錄變成Git可以管理的倉庫:

$ git init
Initialized empty Git repository in /home/my/docker_storage/test/.git/

瞬間Git就把倉庫建好了,而且告訴你是一個空的倉庫(empty Git repository),細心的讀者可以發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裏面的文件,不然改亂了,就把Git倉庫給破壞了。

如果你沒有看到.git目錄,那是因爲這個目錄默認是隱藏的,用ls -ah命令就可以看見。

注:(也不一定必須在空目錄下創建Git倉庫,選擇一個已經有東西的目錄也是可以的。不過,不建議你使用自己正在開發的公司項目來學習Git,否則造成的一切後果概不負責。)

首先這裏再明確一下,所有的版本控制系統,其實只能跟蹤文本文件的改動,比如TXT文件,網頁,所有的程序代碼等等,Git也不例外。版本控制系統可以告訴你每次的改動,比如在第5行加了一個單詞“Linux”,在第8行刪了一個單詞“Windows”。而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但沒法跟蹤文件的變化,只能把二進制文件每次改動串起來,也就是隻知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統不知道,也沒法知道。不幸的是,不幸的是,Microsoft的Word格式是二進制格式,因此,版本控制系統是沒法跟蹤Word文件的改動的

因爲文本是有編碼的,比如中文有常用的GBK編碼,日文有Shift_JIS編碼,如果沒有歷史遺留問題,強烈建議使用標準的UTF-8編碼,所有語言使用同一種編碼,既沒有衝突,又被所有平臺所支持。

windows不要使用自帶的記事本,會出各種問題,用Notepad++代替。記得把Notepad++的默認編碼設置爲UTF-8 without BOM即可:
在這裏插入圖片描述

3.2、git命令把文件添加到版本庫

首先,創建一個readme.txt文檔(位於上面創建的路徑下)。

  /home/my/docker_storage/test$ touch readme.txt

添加內容如下:

Git is a version control system.
Git is free software.

第二步,用命令git add告訴Git,把文件添加到倉庫:

$ git add readme.txt

執行上面的命令,沒有任何顯示,這就對了,Unix的哲學是“沒有消息就是好消息”(真騷),說明添加成功。
第三步,用命令git commit告訴Git,把文件提交到倉庫:

$ git commit -m "wrote a readme file"

出現以下錯誤提示:

*** Please tell me who you are.

Run

  git config --global user.email "[email protected]"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <westwell@6239aa56f0da.(none)>) not allowed

原來是沒有配置name跟Email,配置好之後再次運行$ git commit -m "wrote a readme file"。結果如下:

[master (root-commit) fcdb1c3] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

解釋:git commit命令,-m後面輸入的是本次提交的說明,可以輸入任意內容,當然最好是有意義的,這樣你就能從歷史記錄裏方便地找到改動記錄。
git commit命令執行成功後會告訴你,1 file changed:1個文件被改動(我們新添加的readme.txt文件);2 insertions:插入了兩行內容(readme.txt有兩行內容)。

爲什麼Git添加文件需要addcommit一共兩步呢?因爲commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:

$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

3.3、git版本回退命令

首先,修改readme.txt文件如下:

Git is a distributed version control system.
Git is free software distributed under the GPL.

然後嘗試提交:

$ git add readme.txt
$ git commit -m "append GPL"
[master 1094adb] append GPL
 1 file changed, 1 insertion(+), 1 deletion(-)

像這樣,你不斷對文件進行修改,然後不斷提交修改到版本庫裏,就好比玩RPG遊戲時,每通過一關就會自動把遊戲狀態存盤,如果某一關沒過去,你還可以選擇讀取前一關的狀態。有些時候,在打Boss之前,你會手動存盤,以便萬一打Boss失敗了,可以從最近的地方重新開始。Git也是一樣,每當你覺得文件修改到一定程度的時候,就可以“保存一個快照”,這個快照在Git中被稱爲commit。一旦你把文件改亂了,或者誤刪了文件,還可以從最近的一個commit恢復,然後繼續工作,而不是把幾個月的工作成果全部丟失。

版本控制系統肯定有某個命令可以告訴我們歷史記錄,在Git中,我們用git log命令查看:

commit e0ae91825fb0fbaf886a91f09baae0eda1359d7b
Author: tyy <[email protected]>
Date:   Sun Aug 4 01:58:55 2019 +0000

    append GPL

commit fcdb1c3632b478f6549b9a51c7a5741f6b94e1b6
Author: tyy <[email protected]>
Date:   Sat Aug 3 13:05:55 2019 +0000

    wrote a readme file

再添加一個版本:

Git is a distributed version control system.
Git is free software distributed under the GPL.
the third.
$ git add readme.txt
t$ git commit -m "the third"
[master 1a3d735] the third
 1 file changed, 1 insertion(+)

如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上--pretty=oneline參數:

$ git log --pretty=oneline
1a3d73508f7a4da12a4e43cfd77b4b0561ff39c1 the third
e0ae91825fb0fbaf886a91f09baae0eda1359d7b append GPL
fcdb1c3632b478f6549b9a51c7a5741f6b94e1b6 wrote a readme file

現在,準備把readme.txt回退到上一個版本(第一個):

首先,Git必須知道當前版本是哪個版本,在Git中,用HEAD表示當前版本(第一行,不知道爲什麼沒有head關鍵詞,可能版本不對),也就是最新的提交1a3d73...(注意我的提交ID和你的肯定不一樣),上一個版本就是HEAD^ ,上上一個版本就是HEAD^^ ,當然往上100個版本寫100個^ , 比較容易數不過來,所以寫成HEAD~100

方式:把當前版本append GPL回退到上一個版本append GPL,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at e0ae918 append GPL

打開readme.txt,變回之前的版本,如下:

Git is a distributed version control system.
Git is free software distributed under the GPL.

此時輸入git log 發現最新的third不見了。

$ git log --pretty=oneline
e0ae91825fb0fbaf886a91f09baae0eda1359d7b append GPL
fcdb1c3632b478f6549b9a51c7a5741f6b94e1b6 wrote a readme file

git回到未來的版本方式:在命令端口往上找,找到那個thirdcommit id1a3d735...,於是就可以指定回到未來的某個版本:

$ git reset --hard 1a3d735
HEAD is now at 1a3d735 the third

現在打開readme.回到了最新的版本

Git is a distributed version control system.
Git is free software distributed under the GPL.
the third.

如果,已經關掉了命令端口,找不到之前的commit id。Git提供了一個命令git reflog用來記錄你的每一次命令:

$ git reflog
1a3d735 HEAD@{0}: reset: moving to 1a3d735
e0ae918 HEAD@{1}: reset: moving to HEAD^
1a3d735 HEAD@{2}: commit: the third
e0ae918 HEAD@{3}: commit: append GPL
fcdb1c3 HEAD@{4}: commit (initial): wrote a readme file

3.5、git工作區和暫存區命令

工作區(Working Directory):電腦裏能看到的目錄,比如我的test文件夾就是一個工作區。
暫存區:stage
版本庫(Repository):工作區的隱藏目錄.git
git status:查看工作區狀態

$ git status
On branch master
nothing to commit, working directory clean

在這裏插入圖片描述

3.6、git管理修改命令

爲什麼Git比其他版本控制系統設計得優秀,因爲Git跟蹤並管理的是修改,而非文件
git diff :是隻比較比較工作區和暫存區(最後一次add)的區別;
git diff --cached :是隻比較暫存區和版本庫的區別;
git diff HEAD -- filename :是隻比較工作區和版本庫(最後一次commit)的區別。

3.7、git撤銷修改命令

只在工作區的修改使用:
git checkout -- readme.txt:意思就是,把readme.txt文件在工作區的修改全部撤銷

若使用了add命令提交到了暫存區:
先使用git reset HEAD readme.txt,當我們用HEAD時,表示最新的版本,然後在使用git checkout -- readme.txt
若使用了commit命令提交到了版本庫:

3.8、git刪除文件命令

git rm:刪掉文件

3.9.0、git遠程倉庫

創建SSH Key:

$ ssh-keygen -t rsa -C "[email protected]"

然後一路回車,使用默認值即可,由於這個Key也不是用於軍事目的,所以也無需設置密碼

3.9、git添加遠程庫命令

首先,登陸GitHub,然後,在右上角找到“Create a new repo”按鈕,創建一個新的倉庫:
在這裏插入圖片描述
在Repository name填入test,其他保持默認設置,點擊“Create repository”按鈕,就成功地創建了一個新的Git倉庫:
現在,我們根據GitHub的提示,在本地的learngit倉庫下運行命令:

$ git remote add origin [email protected]:yytang25/test.git

下一步,就可以把本地庫的所有內容推送到遠程庫上:

$ git push origin master

然而,出現Permission denied (publickey)這樣的報錯:

$ git push -u origin master
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

解決辦法點這

git push origin master:此後,每次本地提交後,只要有必要,就可以使用這個命令,推送最新修改;

3.10、git從遠程庫克隆命令

首先,登陸GitHub,創建一個新的倉庫,名字叫gitskills

現在,遠程庫已經準備好了,下一步是用命令git clone克隆一個本地庫:

git clone [email protected]:yytang25/gitskills.git

3.11.0、git分支管理

使用分支意味着你可以從開發主線上分離開來,然後在不影響主線的同時繼續工作。有人把 Git 的分支模型稱爲必殺技特性,而正是因爲它,將 Git 從版本控制系統家族裏區分出來。

3.11、git創建與合併分支命令

查看分支:git branch
創建分支:git branch <name>
切換分支:git checkout <name>
創建+切換分支:git checkout -b <name>
合併某分支到當前分支git merge <name>
刪除分支:git branch -d <name>

3.12、git解決衝突命令

Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容
git log --graph:命令可以看到分支合併圖

3.13、git分支管理策略命令

合併分支時,加上--no-ff參數就可以用普通模式合併,合併後的歷史有分支,能看出來曾經做過合併,而fast forward合並就看不出來曾經做過合併。

3.14、git的Bug分支命令

每個bug都可以通過一個新的臨時分支來修復,修復後,合併分支,然後將臨時分支刪除。

Git還提供了一個stash功能,可以把當前工作現場“儲藏”起來,等以後恢復現場後繼續工作:
git stash apply:恢復,但是恢復後,stash內容並不刪除,你需要用git stash drop來刪除;

git stash pop:恢復的同時把stash內容也刪了

3.15、git的Feature分支命令

開發一個新feature,最好新建一個分支;
如果要丟棄一個沒有被合併過的分支,可以通過git branch -D <name>強行刪除。

3.16、git多人協作命令

git remote:查看遠程庫的信息
git remote -v:顯示遠程庫更詳細的信息

因此,多人協作的工作模式通常是這樣:

  • 首先,可以試圖用git push origin <branch-name>推送自己的修改;
  • 如果推送失敗,則因爲遠程分支比你的本地更新,需要先用git pull試圖合併;
  • 如果合併有衝突,則解決衝突,並在本地提交;
  • 沒有衝突或者解決掉衝突後,再用git push origin <branch-name>推送就能成功!
  • 如果git pull提示no tracking information,則說明本地分支和遠程分支的鏈接關係沒有創建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>

這就是多人協作的工作模式,一旦熟悉了,就非常簡單。

3.17、git的Rebase命令

rebase操作可以把本地未push的分叉提交歷史整理成直線;
rebase的目的是使得我們在查看歷史提交的變化時更容易,因爲分叉的提交需要三方對比。

3.18.0、標籤管理

發佈一個版本時,我們通常先在版本庫中打一個標籤(tag),這樣,就唯一確定了打標籤時刻的版本。將來無論什麼時候,取某個標籤的版本,就是把那個打標籤的時刻的歷史版本取出來。所以,標籤也是版本庫的一個快照。

3.18、git創建標籤命令

git tag <name>:打一個新標籤
git tag -a <tagname> -m "blablabla...":可以指定標籤信息
git tag:查看所有標籤
git show <tagname>:查看標籤信息
比方說要對add merge這次提交打標籤,它對應的commit id是f52c633,敲入命令:

$ git tag v0.9 f52c633

3.19、git操作標籤命令

git push origin <tagname>:可以推送一個本地標籤;
git push origin --tags:可以推送全部未推送過的本地標籤;
git tag -d <tagname>:可以刪除一個本地標籤;
git push origin :refs/tags/<tagname>:可以刪除一個遠程標籤。

3.20、git使用GitHub命令

如何參與一個開源項目呢?比如人氣極高的bootstrap項目,這是一個非常強大的CSS框架,你可以訪問它的項目主頁https://github.com/twbs/bootstrap,點“Fork”就在自己的賬號下克隆了一個bootstrap倉庫,然後,從自己的賬號下clone:

  • 在GitHub上,可以任意Fork開源倉庫;
  • 自己擁有Fork後的倉庫的讀寫權限;
  • 可以推送pull request給官方倉庫來貢獻代碼。

3.21、git使用碼雲命令

3.22.0、自定義git

讓Git顯示顏色,會讓命令輸出看起來更醒目:

$ git config --global color.ui true

3.22、git忽略特殊文件命令

忽略某些文件時,需要編寫.gitignore

.gitignore文件本身要放到版本庫裏,並且可以對.gitignore做版本管理!

不需要從頭寫.gitignore文件,GitHub已經爲我們準備了各種配置文件,只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽:https://github.com/github/gitignore

3.23、git配置別名命令

我們只需要敲一行命令,告訴Git,以後st就表示status:
當然還有別的命令可以簡寫,很多人都用co表示checkout,ci表示commit,br表示branch:
在撤銷修改一節中,我們知道,命令git reset HEAD file可以把暫存區的修改撤銷掉(unstage),重新放回工作區。既然是一個unstage操作,就可以配置一個unstage別名:
配置一個git last,讓其顯示最後一次提交信息:

$ git config --global alias.st status
$ 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'

甚至還有人喪心病狂地把lg配置成了:

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的時候,加上–global是針對當前用戶起作用的,如果不加,那隻針對當前的倉庫起作用。

3.24、git搭建Git服務器命令

第一步,安裝git:

$ sudo apt-get install git

第二步,創建一個git用戶,用來運行git服務:

$ sudo adduser git

第三步,創建證書登錄:

收集所有需要登錄的用戶的公鑰,就是他們自己的id_rsa.pub文件,把所有公鑰導入到/home/git/.ssh/authorized_keys文件裏,一行一個。

第四步,初始化Git倉庫:

$ sudo git init --bare sample.git

第五步,禁用shell登錄:通過編輯/etc/passwd文件完成

git:x:1001:1001:,,,:/home/git:/bin/bash
改爲:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

第六步,克隆遠程倉庫:

$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.

四、常用git命令總結:

git config --global user.name "Your Name":定義name
git config --global user.email "[email protected]":定義email
git init:初始化一個Git倉庫
git add <file>:可反覆多次使用,添加多個文件到git倉庫
git commit -m <message>提交文件到git倉庫
git log:查看提交歷史記錄(從最近到最遠)
git reset --hard commit_id^:回退到之前版本(上一個)
git log:可以查看提交歷史,以便確定要回退到哪個版本
git reflog:查看命令歷史,以便確定要回到未來的哪個版本
git status查看一下工作區狀態
git diff HEAD -- readme.txt命令可以查看工作區和版本庫裏面最新版本的區別
git diff :是隻比較比較工作區和暫存區(最後一次add)的區別;
git diff --cached :是隻比較暫存區和版本庫的區別;
git diff HEAD -- filename :是隻比較工作區和版本庫(最後一次commit)的區別。
git checkout -- readme.txt:意思就是,把readme.txt文件在工作區的修改全部撤銷
git rm:刪掉文件
git remote add origin [email protected]:yytang25/test.git:關聯一個遠程庫
git push -u origin master:第一次推送master分支的所有內容
git push origin master:推送每次最新修改
git clone:克隆一個本地庫
ssh-keygen -t rsa -C "[email protected]":創建SSH Key

查看分支:git branch
創建分支:git branch <name>
切換分支:git checkout <name>
創建+切換分支:git checkout -b <name>
合併某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>

Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容
git log --graph:命令可以看到分支合併圖

合併分支時,加上--no-ff參數就可以用普通模式合併,合併後的歷史有分支,能看出來曾經做過合併,而fast forward合並就看不出來曾經做過合併。

git stash:把當前工作現場“儲藏”起來,等以後恢復現場後繼續工作
git stash apply:恢復,但是恢復後,stash內容並不刪除,你需要用git stash drop來刪除;
git stash pop:恢復的同時把stash內容也刪了

git branch -D <name>:強行刪除丟棄一個沒有被合併過的分支

查看遠程庫信息,使用git remote -v
本地新建的分支如果不推送到遠程,對其他人就是不可見的;
從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠程的新提交;
在本地創建和遠程分支對應的分支,使用git checkout -b branch-name origin/branch-name,本地和遠程分支的名稱最好一致;
建立本地分支和遠程分支的關聯,使用git branch --set-upstream branch-name origin/branch-name
從遠程抓取分支,使用git pull,如果有衝突,要先處理衝突。

git tag <name>:打一個新標籤
git tag -a <tagname> -m "blablabla...":可以指定標籤信息
git tag:查看所有標籤
git show <tagname>:查看標籤信息

git push origin <tagname>:可以推送一個本地標籤;
git push origin --tags:可以推送全部未推送過的本地標籤;
git tag -d <tagname>:可以刪除一個本地標籤;
git push origin :refs/tags/<tagname>:可以刪除一個遠程標籤。

$ git config --global color.ui true:讓命令輸出看起來更醒目

$ git config --global alias.st status:替換關鍵詞

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