30分鐘教你學會Git

2021-02-21 極客標籤社區

Git近些年的火爆程度非同一般,這個版本控制系統被廣泛地用在大型開源項目(比如Linux),不同規模的團隊開發,以及獨立開發者,甚至學生之中。

初學者非常容易被git裡的各種命令、參數嚇得不願意繼續去學。但實際上剛上手的時候,你並不需要了解所有命令的用途。你可以從掌握一些簡單、常用又強大的命令開始,然後逐步去學習。這就是我們這篇文章要講的內容。讓我們快開始吧!


基本了解

Git是一些命令行工具的集合,可以用來跟蹤、記錄文件的變動,經常用於開原始碼。比如你可以進行舊版本恢復、比對、分析、合併等等。這個過程被稱之為版本控制。已經有一系列的版本控制系統,比如SVN、Mercurial、Perforce、CVS、Bitkeepe等等。

Git是分布式的,這意味著它並不依賴於中心伺服器來保存你文件的舊版本。任何一臺機器都可以有一個本地版本的控制系統,其實就是一個硬碟上的文件,我們稱之為倉庫(repository)。如果是多人協作的話,你還需要一個線上倉庫,用來同步代碼等信息。這就是GitHub、BitBucket等網站做的工作。

1.安裝Git

在你的機器上安裝git非常簡單:

Linux – 打開終端,然後通過包管理安裝,在Ubuntu上命令是:sudo apt-get install git

Windows – 推薦使用git for windows,它包括了圖形工具以及命令行模擬器。

OS X – 最簡單的方式是使用homebrew安裝,命令行執行brew install git

如果你是新手,推薦使用圖形工具Github desktop和Sourcetree。不過即使使用圖形界面的應用,知道一些基本的git命令依然很重要。接下來的內容我們集中在命令行控制上。

2.配置Git

安裝完git,首要任務是做一些簡單的配置,最重要的是用戶名及郵箱,打開終端,執行以下命令。

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

配置好這兩項,Git就能記錄下來是誰做的動作,一切都更有組織性了。

3.創建一個新倉庫 – git init

git會把所有文件以及歷史記錄直接記錄成一個文件夾保存在你的項目中。創建一個新的倉庫,首先要去到項目路徑下,執行git init。這時Git會創建一個隱藏的文件夾.git,所有的歷史和配置信息都儲存在其中。

比如我們在桌面創建一個文件夾 git_exercise, 打開終端,輸入:

$ cd Desktop/git_exercise/ 
$ git init

命令行會出現

Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/

這說明我們的倉庫已經建立好了,但現在是空的,試著新建一個hello.txt文本文件到這個文件夾裡。

4.檢查狀態 – git status

Git status是另一個非常重要的命令,它反饋給我們倉庫當前狀態的信息:是否為最新代碼,有什麼更新等等。在我們新建的倉庫中執行git status會得到以下內容:

$ git status 
On branch master 
Initial commit 
Untracked files: 
  (use "git add ..." to include in what will be committed) 
hello.txt

反饋信息告訴我們,hello.txt尚未跟蹤,這是說這個文件是新的,git不知道是應該跟蹤它的變動還是直接忽略。為了跟蹤我們的新文件,我們需要暫存它。

5.暫存 – git add

Git有個概念叫「暫存區「,你可以把它看成一塊空白的畫布,包裹著所有你可能會提交的變動。它一開始是空的,可以通過 git add 命令添加內容,最後使用 git commit 提交(創建一個快照)。

這個例子中只有一個文件,讓我們先add它:

$ git add hello.txt

如果需要提交目錄下的所有內容,可以這樣做:

$ git add -A

再次使用git status查看狀態試試:

$ git status 
On branch master 
Initial commit 
Changes to be committed: 
  (use "git rm --cached ..." to unstage) 
new file:   hello.txt

我們的文件已經準備好可以提交了。狀態信息還告訴我們暫存區文件發生了什麼變動,這裡我們新增了一個文件,同樣可以做修改和刪除。取決於我們在上一次git add之後發生了什麼。

6.提交 – git commit

一次提交代表著我們的倉庫到了一個新的狀態,就像是一個快照,允許我們像使用時光機一樣回到之前的某個時間點。

創建提交,需要我們至少在到暫存區有一次修改(剛才我們做了git add),然後輸入命令:

$ git commit -m "Initial commit."

這就創建了一次從暫存區的提交(加入hello.txt),-m 「Initial commit.」是用戶對這次提交的描述,建議寫成有意義的描述性信息。


遠程倉庫

到目前為止,我們的操作都是在本地的——只存在於.git文件中。為了能夠協同開發,我們需要把代碼部署到遠程倉庫伺服器上。

1.連結遠程倉庫 – git remote add

為了能夠上傳到遠程倉庫,我們需要先建立起連結。在這篇教程中,我們遠程倉庫的地址為:https://github.com/igeekbar/awesome-project。但你應該自己在Github、或BitBucket上搭建倉庫,自己一步一步嘗試。

把本地倉庫連結到Github上,在命令行執行以下內容:

# This is only an example. Replace the URI with your own repository address. 
$ git remote add origin https://github.com/igeekbar/awesome-project.git

一個項目可以同時擁有好幾個遠程倉庫,為了區分通常會起不同的名字。通常主要的遠程倉庫被稱為origin。

2.上傳到伺服器 – git push

把本地的提交傳送到伺服器的動作叫做push。每次我們要提交修改到伺服器上時,都會使用到git push。

git push命令有兩個參數,遠程倉庫的名字,以及分支的名字:

$ git push origin master 
Counting objects: 3, done. 
Writing objects: 100% (3/3), 212 bytes | 0 bytes/s, done. 
Total 3 (delta 0), reused 0 (delta 0) 
To https://github.com/igeekbar/awesome-project.git 
 * [new branch]      master -> master

取決於你使用的伺服器,push過程中你可能需要驗證身份(輸入用戶名、密碼,請先在網站上進行註冊)。如果沒有出差錯,現在用瀏覽器看你的遠程倉庫上已經有hello.txt了。

3.克隆倉庫 – git clone

其他人可以看到你放在Github上的開源項目,他們可以用git clone命令下載到本地。

$ git clone https://github.com/igeekbar/awesome-project.git

本地也會創建一個新的倉庫,並自動將github上的版本設為遠程倉庫。

4.從伺服器上獲得修改 – git pull

如果你更新了遠程倉庫上的內容,其他人可以通過git pull命令拉取你的變動:

$ git pull origin master 
From https://github.com/igeekbar/awesome-project 
 * branch            master     -> FETCH_HEAD 
Already up-to-date.

因為在我們git clone之後還沒有提交過修改,所有沒有任何變動。


分支

當你在做一個新功能的時候,最好是在一個獨立的區域上開發(原始項目的拷貝),通常稱之為分支。分支之間相互獨立,並且擁有自己的歷史記錄,直到你決定把他們合併到一起。這樣做的原因是:


1.創建新分支 – git branch

每一個倉庫的默認分支都叫master, 創建新分支可以用git branch <name>命令:

$ git branch amazing_new_feature

創建了一個名為amazing_new_feature的新分支,它目前和master分支是一樣的內容。


2.切換分支 – git checkout

使用git branch,可以查看分支狀態:

$ git branch 
  amazing_new_feature 
* master

* 號表示當前活躍分支為master,現在我們想在新分支上開發新的特性,使用git checkout切換分支。有一個參數表示要切換到的分支。

$ git checkout amazing_new_feature


3.合併分支 – git merge

我們在「amazing_new_feature」分支想添加一個feature.txt。和之前一樣我們來創建文件、添加到暫存區、提交。

$ git add feature.txt 
$ git commit -m "New feature complete."

新分支任務完成了,回到master分支。

$ git checkout master

現在去查看文件夾內容,你會驚奇地發現之前剛剛創建的feature.txt文件不見了,因為我們現在回到了master分支上,這裡並沒有feature.txt。想把文件添加到這裡,我們需要使用git merge把amazing_new_feature分支合併到master上。

$ git merge amazing_new_feature

現在master分支是最新的了,amazing_new_feature分支可以刪掉了。

$ git branch -d amazing_new_feature


進階功能

在這篇教程的最後一節,我們來看一些高級並且實用的技巧。

1.比對兩個不同提交之間的差別

每次提交都有一個標識id,查看所有歷史提交和他們的id,可以使用 git log:

$ git log 
commit ba25c0ff30e1b2f0259157b42b9f8f5d174d80d7 
Author: igeekbar 
Date:   Fri July 29 17:15:28 2016 +0300 
    New feature complete 
commit b10cc1238e355c02a044ef9f9860811ff605c9b4 
Author: igeekbar 
Date:    Fri July 29 16:30:04 2016 +0300 
    Added content to hello.txt 
commit 09bd8cc171d7084e78e4d118a2346b7487dca059 
Author: igeekbar 
Date:   Thu July 28 17:52:14 2016 +0300 
    Initial commit

id很長,但是當使用它的時候你並不需要複製整個字符串,前幾個字符就夠了。

查看某一次提交更新了什麼,使用 git show [commit]:

$ git show b10cc123 
commit b10cc1238e355c02a044ef9f9860811ff605c9b4 
Author: igeekbar 
Date:    Fri July 29 16:30:04 2016 +0300 
    Added content to hello.txt 
diff --git a/hello.txt b/hello.txt 
index e69de29..b546a21 100644 
--- a/hello.txt 
+++ b/hello.txt 
@@ -0,0 +1 @@ 
+Nice weather today, isn't it?

查看兩次提交的不同,可以使用git diff [commit-from]..[commit-to]:

$ git diff 09bd8cc..ba25c0ff 
diff --git a/feature.txt b/feature.txt 
new file mode 100644 
index 0000000..e69de29 
diff --git a/hello.txt b/hello.txt 
index e69de29..b546a21 100644 
--- a/hello.txt 
+++ b/hello.txt 
@@ -0,0 +1 @@ 
+Nice weather today, isn't it?

比較首次提交和最後一次提交,我們可以看到中間所有的更改。使用git difftool命令可以用圖形化界面查看所有更改。

2.回滾某個文件到之前的版本

Git允許我們將某個特定的文件回滾到特定的提交,使用的也是 git checkout命令。

下面我們將hello.txt回滾到最初的狀態,需要指定回滾到哪個提交(以id作為參數),以及文件的全路徑。

$ git checkout 09bd8cc1 hello.txt

3.回滾提交

如果你發現最新的一次提交忘記加入某個文件,或是信息輸入的不正確,你可以通過 git commit --amend來改正,它會把最新的提交打回暫存區,並嘗試重新提交。

如果是更複雜的情況,比如不是最新的提交除了問題,你可以使用git revert。

最新的一次提交別名也叫HEAD。

$ git revert HEAD

其他提交需要指明id:

$ git revert b10cc123

回滾提交時,發生衝突是非常頻繁的。比如文件被指定回滾的提交之後的某次提交修改過,git不能正確回滾。

4.解決合併衝突

衝突經常出現在合併分支或者是拉取別人的代碼。有些時候git能自動處理衝突,其他時候需要我們手動處理。

我們來看以下的例子,John 和 Tim 分別在各自的分支上寫了一段代碼,來顯示一個數組中所有的元素。

John使用了for循環:

// Use a for loop to console.log contents. 
for(var i=0; i<arr.length; i++) { 
console.log(arr[i]); 
}

Tim使用forEach:

// Use forEach to console.log contents. 
arr.forEach(function(item) { 
console.log(item); 
});

它們都提交了代碼到各自的分支上,現在假設John嘗試合併Tim的代碼:

$ git merge tim_branch 
Auto-merging print_array.js 
CONFLICT (content): Merge conflict in print_array.js 
Automatic merge failed; fix conflicts and then commit the result.

這時候git並不能自動解決衝突,於是它在代碼中插入衝突標記。

<<<<<<< HEAD 
// Use a for loop to console.log contents. 
for(var i=0; i<arr.length; i++) { 
    console.log(arr[i]); 

======= 
// Use forEach to console.log contents. 
arr.forEach(function(item) { 
    console.log(item); 
}); 
>>>>>>> Tim’s commit.

==== 號上方是當前最新一次提交,下方是衝突的代碼。這樣我們可以清晰地看出區別,決定使用哪一個版本,或者重新寫一個。假設我們對於這兩個版本都不滿意,我們把代碼改成以下代碼:

// Not using for loop or forEach. 
// Use Array.toString() to console.log contents. 
console.log(arr.toString());

好了,再提交一下:

$ git add -A 
$ git commit -m "Array printing conflict resolved."

在大型項目中,我們可能在合併過程中出現很多衝突,大部分開發者會藉助GUI工具來獲得幫助,運行推行界面可以使用git mergetool命令。

5.配置 .gitignore

大部分項目中,會有些文件、文件夾是我們不想提交的。為了防止使用git add -A時不小心提交,我們可以利用.gitignore文件:

通常會被ignore的文件有:

以下是一個.gitignore文件的例子:

*.log 
build/ 
node_modules/ 
.idea/ 
my_notes.txt

「/」說明是一個文件夾,裡面的所有內容都被遞歸忽略

總結

Git教程到這裡就結束啦!

Git很複雜,還有很多的特性和技巧等著你去挖掘,這篇教程只涵蓋了冰山一角,希望你不要因為太多繁瑣的命令而停下前進的腳步!加油!

相關焦點

  • 20 分鐘教你搞懂 Git!
    以下為譯文:儘管每天你都會用到Git,但也有可能搞不懂它的工作原理。為什麼Git可以管理版本?$ cat .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391上述代碼輸出的文件內容是一些二進位字符。你可能會問既然test.txt是空文件,又怎麼會有這些內容呢?這是因為該二進位對象中還存儲了一些元數據。如果你想看看該文件原始的文本內容,那麼應該使用git cat-file。
  • 30 分鐘 git 命令入門到放棄
    -30-minutes/這是一篇給像我這樣的新手或者是熟悉圖形工具的老鳥看的。5.暫存 – git addgit 有個概念叫 暫存區,你可以把它看成一塊空白帆布,包裹著所有你可能會提交的變動。它一開始為空,你可以通過 git add 命令添加內容,並使用 git commit 提交。
  • 一篇文章,教你學會Git
    暫存區標記了你當前工作區中,哪些內容是被git管理的。當你完成某個需求或功能後需要提交到遠程倉庫,那麼第一步就是通過 git add 先提交到暫存區,被git管理。保存了對象被提交 過的各個版本,比起工作區和暫存區的內容,它要更舊一些。
  • 30分鐘吃掉Git和GitHub常用操作
    配置用戶信息git config --global user.name "XX"git config --global user.email "XX@XX"新建文件夾並切入mkdir git-learncd git-learn創建倉庫git init新建readme.txtecho "hello
  • Git發布2.30版本
    Git 2.30版本已於北京時間今天凌晨3點發布,是該廣受歡迎的分布式修訂版本控制系統的最新穩定版本更新,Git由Linux內核發明者Linus大神於2005年推出。
  • Git 版本控制,看這篇就夠了 (一)
    可以流暢的參與多人協作,本文致力於快速的入門,學會完本文以後日常使用已經完全足夠了,如果涉及到更高級的功能需要進行更深一步的學習。如果以Fedora上為例,你可以使用yum: $ sudo yum install git如果你在基於Debian的發行版上,請嘗試用apt-get: $ sudo apt-get install git要了解更多選擇,Git官方網站上有各種Unix風格的系統上安裝步驟,網址為https://git-scm.com
  • 這才是真正的Git——Git實用技巧
    rebase -i 是個很實用且應用廣泛的工具,希望大家都學會它的使用。它還可以用來修改commit信息,拋棄某些commit,對commit進行排序等等。具體命令如下,操作方式跟動圖一致,都是在vim裡面進行編輯。這裡不展開,感興趣的同學可以自己操作一下。
  • 一張腦圖帶你徹底掌握Git
    一張腦圖帶你徹底掌握Git北遊小屋2020-10-28 22:03:39首先我們的了解Git通常的操作流程,網上流行的不錯一張圖Git腦圖基本概念基於上面的圖,我們就有接下來一些概念版本庫.git當我們使用git管理文件時,比如git init時,這個時候,會多一個.git文件,我們把這個文件稱之為版本庫
  • 你不知道的Git
    這時當他想更新代碼,老李說我更新代碼了你先pull一下,於是就產生了上面的問題!!!產生原因:多人操作場景,其中一人將代碼提交到遠程git,另一個人也修改了文件準備pull的時候會產生該問題;解決方案一:保留本地新修改的代碼。
  • 困擾你的Git操作?
    upstream:指上遊,fork 別人項目的地址,別人的項目就是你的上遊,即上一層源文件。master:指主分支。pull:指拉代碼,把你 Github 上的遠程倉庫拉到本地計算機上。push:指提交代碼,把你本機上的項目提交到 Github 上的遠程倉庫。
  • 一份你女朋友都能讀懂的 Git 教程,還不趕緊學起來!
    嚴肅寫作的一個個節點iOS 上的知名筆記工具 Drafts 會在你寫作時,每隔一分鐘幫你保存一份當前文檔的「快照」,這樣就可以方便地找回之前的某個寫作版本了。你覺得不滿意而刪除的一段文字,總可以在歷史版本中找回,很貼心。
  • git環境配置和.gitconfig配置文件詳解
    為此今天蟲蟲專門撰寫本文來介紹下git的基本配置,以幫助大家解疑你遇到一些莫名其妙的問題,答惑為什麼會出現這樣的問題。而實際中這些的出現僅僅是因為你使用了不一樣的配置,而你卻不知道。git的配置文件當你在git伺服器Web管理頁面創建完第一個項目的時候,接下來的一個頁面會提示你做一些基本的git配置,比如github的提示頁面如下:你按照提示這些命令中有一個藍色標註的git remote add命令。實際提到這些命令配置還比較繁瑣,你可以用clone在你的機器上直接創建一個空項目,忽略到上面提示中這許多步驟。
  • 一分鐘教你學會單透貼的安裝方法
    不要著急,一分鐘教你學會單透貼的安裝方法,趕快學習起來吧!單透貼安裝--陝西藝盛廣告一分鐘教你學會單透貼的安裝方法第一步:將玻璃擦乾淨,可用玻璃清潔工具第二步2.遮陽打孔單面透(小孔):透視率達30%且透視效果較差,但廣告畫面較為清晰,附著墨點較多,適用於透視效果要求不高的玻璃面上張貼。3.絲網印刷單面透:透視率可根據需求隨意調整,產品成本較低,但製作工藝繁瑣,透視效果取決於可剝離透明墨的品質和製版工藝,可因材質較硬和附著面積較大,極易引起整體脫落。
  • Git 分支操作介紹
    如果所有人都在你代碼倉庫的 master 分支上操作,會引發很多混亂。對程式語言或項目的知識和閱歷因人而異;有些人可能會編寫有錯誤或缺陷的代碼,也可能會編寫你覺得不適合該項目的代碼。使用分支可以讓你核驗他人的貢獻並選擇適合的加入到項目中。(這裡假設你是代碼庫唯一的所有者,希望對增加到項目中的代碼有完全的控制。
  • 如何規範你的Git commit?
    如果你的修改影響了不止一個scope,你可以使用*代替。subject是commit目的的簡短描述,不超過50個字符。用戶可以在項目根目錄的.git目錄下面配置使用,也可以配置全局git template用於個人pc上的所有git項目使用。服務端hook又分為pre-receive、post-receive、update,主要在服務端接受提交對象時進行調用。以上這種採用webhook的形式對git commit進行監控就是一種server端的hook,相當於post-receive。
  • 1小時搞懂 Git 版本控制
    當時因為需要做一個項目,所以他教我如何使用 Git 將寫好的代碼推送到 GitHub 上,然後再從遠程倉庫拉到本地。起初因為沒有接觸過 Git,覺得這玩意很難學,又是一大堆命令需要記憶,在他教我的時候內心是牴觸的,當時覺得為什麼不把寫好的代碼發送給我呢?你是否也有過這樣的疑問呢?學習 Git 的時候,因為沒有和他認真學,在他教過我一遍之後還是一臉懵逼,寫命令的時候也是不時地回頭查看。
  • 【譯文】Git merge 和 Git rebase比較
    但如果使用得當的話,它能給你的團隊開發省去太多煩惱。在這篇文章中,我們會比較git rebase和類似的git merge命令,找到Git工作流中rebase的所有用法。概述   你要知道的第一件事是,git rebase 和git merge 做的事其實是一樣的。它們都被設計來將一個分支的更改併入另一個分支,只不過他們實現方式有些不同。
  • Git 分支操作介紹 | Linux 中國
    在本系列的前兩篇文章中,我們開始使用 Git[1],學會如何克隆項目,修改、增加和刪除內容[2]。在這第三篇文章中,我將介紹 Git 分支,為何以及如何使用分支。tree branches不妨用樹來描繪 Git 倉庫。圖中的樹有很多分支,或長或短,或從樹幹延伸或從其它分支延伸。
  • 詳細介紹下git中的多種撤銷
    手把手教你入門git,下面我們再介紹下git中關於各種撤銷的操作流程。當你在git倉庫中進行一次新的提交的時,git保存這個特定時間的倉庫的快照,並生產一個唯一串與本次提交相對應。之後,就可以利用 git返回到項目的一個早期版本。下面我們說一些常見的撤銷常見場景,以及 git的命令操作步驟。
  • 這篇文章很贊:Git 入門指南使用資料匯總及文章推薦
    無需網絡,隨時隨地進行版本控制,在沒有網絡的情況下你想回退到某個版本svn基本沒戲;分支的新建、合併非常方便、快速,沒有任何成本,基本不耗時,svn的版本基本上等同於又複製了一份代碼;stackoverflow 上關於svn和git的區別的討論,說的很詳細,請參考 Why is Git better than Subversion?